Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check if a variable really responds_to :dup?

Tags:

ruby

I wanted to use value.respond_to?(:dup) ? value.dup : value in order to check if I can duplicate an object but it failed with TypeError on booleans, nil or such "primitives" alike.

I've ended up with:

begin
  value = value.dup
rescue
  #ignore, use the original if no dup-able (e.g nil, true, etc)
end

Is there a better way?

Bonus: Why does it responds :dup?

Not deep dup, just for the question.

EDIT: Thoughts:

  • obj.class.methods.include? :new is nice but a bit too hackish i think it has bad performance
  • Marshal also looks like an overkill
  • one line rescue could have been the best solution, but type specific one line rescue is not possible at this time (IIUC matz is on that!), and as @JörgWMittag mentioned its wrong.
  • Personally i think dup being defined at the object level is wrong.

So, quoting @Linuxios

There isn't really a better way

like image 645
Hertzel Guinness Avatar asked Jan 06 '14 16:01

Hertzel Guinness


1 Answers

You can write it as one line this way:

value = value.dup rescue value

Very clear.

It is standard to define a dup method that raises TypeError for types that cannot be duplicated. Thus any object will "respond to" it. You really have to call it and check with a begin-rescue-end.

like image 88
Guilherme Bernal Avatar answered Sep 28 '22 06:09

Guilherme Bernal