Bob Hutchison wrote: > Hi, > > On Jul 21, 2006, at 11:10 PM, John W. Long wrote: > >> Jamey Cribbs wrote: >>> The way it works is that in the Plane.find method, I grab the block >>> and pass it to #instance_eval. This executes the block in the Plane >>> classes environment, so it knows that when it sees the attribute >>> "speed" or "country" in the block, it knows to call Plane.speed and >>> Plane.country. Planes.speed happens to be a reference to a >>> SkiplistColumn instance and it knows how to handle the "> 350" >>> passed to it. >> >> The problem with this approach is that you loose access to instance >> variables. For instance: >> >> >> class Object >> >> def with(&block) >> >> instance_eval(&block) >> >> end >> >> end >> => nil >> >> @test = 1 >> => 1 >> >> Object.new.with { puts @test } >> => nil >> >> In the above example @test when used within the context of the with >> block is thought to be an instance variable of the object, which is >> why it returns nil instead of 1. I consider this behavior undesirable. > > > Is this really a problem? If we write it this way: > > class Object > def with(&block) > instance_eval(&block) > end > end > > class Toy > def play > @test = 'hello there' > with { puts "!!!! [#{@test}] !!!!" } > end > end > > toy = Toy.new > toy.play > > you get the output: > > !!!! [hello there] !!!! > > which is using the @test as I think you want. I think the following code is an example of what John is pointing out: class Employee def self.find(&block) instance_eval(&block) end end class Department def initialize @dept = 'Accounting' end def employees Employee.find { puts "employee.dept == #{@dept}" } end end Department.new.employees Run this and you get: employee.dept == Replace that instance_eval in Employee.find with a yield statement, run it again, and you get: employee.dept == Accounting If I could be sure that everyone would only do a Table.find in Mongoose from the top level environment, so that variables that they declared would be seen inside the Table class, I would be ok. But, what happens when someone, like the example above, is doing a Table.find from within another object? If I use #instance_eval inside of Table.find, I lose access to the instance variables from the calling object. No, it looks like I will have to go back to doing a yield in Table.find, which means the user is going to have to specify a block parameter in the #find block. In other words: Employee.find { |emp| emp.dept == @dept } I guess it doesn't look that bad. Jamey