Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

define_method not using variables until method is called?

I'm having trouble getting a variable from a for loop. It seems i(var) is calculated later on and not class definition which I totally require.

ree-1.8.7-2010.02 > class Pat
ree-1.8.7-2010.02 ?>  for i in 39..47
ree-1.8.7-2010.02 ?>    define_method("a#{i}".to_sym) do
ree-1.8.7-2010.02 >         puts i 
ree-1.8.7-2010.02 ?>      end
ree-1.8.7-2010.02 ?>    end
ree-1.8.7-2010.02 ?>  end
#=> 39..47 

ree-1.8.7-2010.02 > p = Pat.new
#=> #<Pat:0x103c31140> 

ree-1.8.7-2010.02 > p.a39
47
#=> nil 

ree-1.8.7-2010.02 > p.a49
NoMethodError: undefined method `a49' for #<Pat:0x103c31140>
    from (irb):69
    from :0
ree-1.8.7-2010.02 > p.a40
47
#=> nil 

Should I be using def? if so how can I achieve the dynamic method names that I achieved here with def.

like image 496
fivetwentysix Avatar asked Apr 05 '11 15:04

fivetwentysix


1 Answers

What's happening there is a bit subtle... the traditional for loop that you're using shares the single "i" variable across all iterations... The closure (block password to define_method) is capturing "i" - and since there is only one "i", they will all (at the end of the for loop) capture the final value of "i", which is the last value in the range that you're looping over.

Alternative solution:

class C
  (1..10).each {|i| define_method("a#{i}") { puts i } }
end
like image 178
Ryan LeCompte Avatar answered Sep 30 '22 22:09

Ryan LeCompte