On Aug 18, 2010, at 11:38 AM, David Chelimsky wrote:

> 
> On Aug 18, 2010, at 11:31 AM, rogerdpack wrote:
> 
>> Sorry if this is a newbie question, but here goes.
>> 
>> I was wondering if the following is somehow possible:
>> 
>> 
>> for file in Dir['*.bmp']
> 
> Use this instead:
> 
> Dir["*.bmp"].each do |file| 
>>   it "should be able to parse #{file}" do
>>     p file
>>     # test this file
>>   end
>> end

The reason, btw, has to do with ruby closures and scope. Ruby blocks are 
closures, which means they have access to the state of the scope in which they 
were defined, but they don't access that state until they are evaluated. By 
using an iterator that takes a block, we end up with two nested closures:

[1,2,3].each do |n|
  it "is #{n}" do
    puts n
  end
end

Here, the first time through the outer iterator, the value of n is 1. The 
string passed to it() is evaluated at this time, so that string is transformed 
to "is 1". The block passed to it() is not eval'd yet, but when it does get 
evaluated it will take on the value of the scope in which it was defined, which 
the block passed to the iterator with its block parameter. This will maintain a 
value of 1.

for n in [1,2,3]
  it "is #{n}" do
    puts n
  end
end

Here, the first time through the outer loop, the value of n is 1. Again, the 
string passed to it() is evaluated at this time, so that string is transformed 
to "is 1".  When the block is eval'd, the scope in which it was defined is the 
same scope in which the loop was defined, so n will have changed to the last 
item in the list, 3.

Does this make sense to you?

Cheers,
David


>> 
>> Currently rspec seems to evaluate the blocks after the fact, leading
>> to "file" always being the last file in the list.
>> I was unsure how to pass a parameter into an "it" block.
>> Thoughts?
>> Thanks.
>> -r
> 
> 

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to