From: Robert Klemme Date: 2007-11-21T01:20:32+09:00 Subject: Re: using lambda, binding happens immediately? 2007/11/20, Sam Larbi : > Robert, > > On Nov 20, 2007 9:27 AM, Robert Klemme wrote: > > > 2007/11/20, Sam Larbi : > > > Thanks Robert, > > > > > > I have some more questions / responses below. > > > > > > > > > On Nov 20, 2007 6:45 AM, Robert Klemme > > wrote: > > > > > > > 2007/11/19, Sam Larbi : > > > > > I have this code: > > > > > > > > > > > > > > > require 'test/unit' > > > > > require 'leapyear' > > > > > class LeapYearTest < Test::Unit::TestCase > > > > > def setup > > > > > @ly = LeapYear.new > > > > > end > > > > > def LeapYearTest.generate_tests > > > > > filename = "testdata.dat" > > > > > file = File.new(filename, "r") > > > > > file.each_line do |line| > > > > > year, is_leap = line.split; > > > > > code = lambda { assert_equal(is_leap.downcase=="true", @ > > ly.isleap > > > > ?( > > > > > year.to_i)) } > > > > > define_method("test_isleap_" + year, code) > > > > > end > > > > > file.close > > > > > end > > > > > end > > > > > > > > > > > > > > > What I want to know is why when I use define_method("name") {block;} > > > > instead > > > > > of define_method("name", lambda{block}) the binding seems to happen > > > > later > > > > > (after the each_line loop)? > > > > > > > > > > Is there a reason behind that? > > > > > > > > I'm not sure I understand you but why don't you just do > > > > > > > > > > Well, the problem is that attaching the block uses only the last "year" > > to > > > be processed in the loop, never the appropriate one. > > > > Then you are using "year" outside the block as well and the code you > > have shown is not the code you actually run. > > > > I tried your code and as you know, it works fine. I even reconstructed the > tests for it, and it still worked fine. > > The problem I had was over a year old, so I wonder if this was only the case > in an older version of Ruby. (Can anyone confirm or deny that?) I'm > certain I had the problem before, but obviously we cannot reproduce it in > this similar case. > > If I can find the old code for the LeapYear class I'll give it a shot and > get back to you. IMHO even older Ruby version should behave the same, i.e. when the variable is used inside the block only then you get multiple copies of it and thus your created methods won't share them. Kind regards robert -- use.inject do |as, often| as.you_can - without end