Friday, December 11, 2015

Ruby "def" Jam

This afternoon I was briefly taken aback by an extra "def" in my Ruby code.

To see what I mean, put the following into a file (e.g. "test.rb"):

def

def a
  puts "hi!"
end

def b
  a
end

b

Now execute it:


$ ruby test.rb
test.rb:7:in `b': undefined local variable or method `a' for main:Object (NameError)
 from test.rb:10:in `
'

If you put enough space in front of the first def and don't have line-wrap so as to hide the extra def, it will probably be non-obvious to others as to why the "b" method can't see "a", as "a" will clearly seem to be defined.

Instead, you defined a method called "def" with a single argument "a". But, notice how we are still able to define the b method with def, even though def seems like it would have been redefined:

$ irb
2.2.3 :001 > def def a
2.2.3 :002?>   puts "hi!"
2.2.3 :003?>   end
 => :def 
2.2.3 :004 > def b
2.2.3 :005?>   puts "world"
2.2.3 :006?>   end
 => :b 
2.2.3 :007 > b
world
 => nil

To use this new def method, you must call it with send.

2.2.3 :008 > send :def, 1
hi!
 => nil 

No comments: