Peter Lacey
1/5/2006 1:11:00 AM
Final post in this thread. It seems that the consensus is that these
two approaches are equal in terms of their results. Knowing that, it
would appear that I _did_ oversimplify my original post. For the
sake of the question I had distilled the active record code to this:
class SingletonBase
class << self
def table_name
reset_table_name
end
def reset_table_name
puts "reset_table_name called"
name = self.name
sing = class << self; self; end
sing.class_eval "def table_name; #{name.inspect}; end"
name
end
end
end
However, the actual code is more (but not exactly, in the interest of
brevity) like this:
class Base
class << self
def table_name
reset_table_name
end
def reset_table_name
name = self.name
set_table_name name
name
end
def set_table_name( value=nil, &block )
sing = class << self; self; end
if value
sing.class_eval "def #{name}; #{value.to_s.inspect}; end"
else
sing.send :define_method, name, &block
end
end
end
end
It would appear, then, that the singleton class is created solely for
handling the optional block parameter, and not, as I originally
suspected, for some more global reason.
Sorry for the wild goose chase and thank you for your insight.
Pete
On Jan 4, 2006, at 6:52 PM, Phil Tomson wrote:
> In article <0B6DAD2D-A02E-4D6E-82F9-2DB8D78A685F@wanderingbarque.com>,
> Peter Lacey <placey@wanderingbarque.com> wrote:
>> On Jan 4, 2006, at 3:47 PM, Phil Tomson wrote:
>>
>>> I'm not so sure it's faster; it uses a class_eval.
>
> ooops, I see that the class_eval is only called once so maybe it's
> correct
> that that version is faster overall.
>
>>
>> There's a comment in the actual active record code that notes that
>> class_eval is used over define_method to get around a memory leak in
>> fcgi.
>>
>> But to Ako's point, it seems to me that there has to be some
>> important difference between the singleton approach and the class
>> instance var approach for several reasons:
>>
>> 1. DHH and the other active record coders and reviewers know what
>> they're doing, and I suspect this seemingly convoluted code wouldn't
>> have survived for very long if it was simply "another way of doing
>> it."
>>
>
>> 3. The active record code _does_ use class instance vars in other
>> places, so this looks very intentional.
>
> I wouldn't be so sure... I suspect that DHH's (and the other Rails
> contributors) Ruby skills and understanding have increased over time
> and maybe if they were writing the code from scratch now they would
> use the
> class instance variable method as opposed to the class_eval
> method. I know
> that I've got a lot of Ruby code out there that I wrote early on
> that I would
> write very differently now... Sometimes code survives because it
> works.
>
>> 2. I'm very new to Ruby, and I don't know what I'm doing. :-)
>>
>> 3. The active record code _does_ use class instance vars in other
>> places, so this looks very intentional.
>
> Like I said above, it's possible that the class instance var meme
> came later
> in the development history of Rails and that they started using it
> after it
> became known to them. Only DHH can say for sure ;-)
>
>
> Phil
>