David Masover
8/24/2008 1:26:00 AM
On Saturday 23 August 2008 20:09:52 Doug Glidden wrote:
> class MyClass
> ...
>
> def add_fields(*field_list)
> class << self
> attr accessor *field_list
> end
> end
> end
[snip]
> Both throw an error because field_list is not defined within the
> singleton class definition? Am I making a simple mistake, or should I
> be doing this differently?
Well, if you actually have fields called :field1, :field2, and :field3, I
might suggest an array... Assuming that's not the case.
I don't even remember the actual Ruby way to do this, but _why's metaid gem
would let you do it like this:
def add_fields(*field_list)
meta_eval do
attr_accessor *field_list
end
end
The key, however, is that it's some sort of _eval method -- that it's taking a
block, which means you get to inherit the parent scope. In fact, if it's
actually a singleton (as in, only one instance of this class will be
defined), you can do this:
def add_fields(*field_list)
self.class.class_eval do
attr_accessor *field_list
end
end
In this case, self.class refers to the actual class that the current object is
an instance of. On the other hand, self.metaclass or meta_eval (both from
metaid) refer to the current object's metaclass, or eigenclass.
Given that you were doing "class << foo" stuff, I'm assuming you wanted the
metaclass.
One more hack before I'm through:
def add_fields(*field_list)
self.metaclass.send :attr_accessor, *field_list
end
I haven't tested any of this. Let me know how it works for you.