From: Doug Glidden <41mortimer@...> Date: 2008-08-24T11:04:52+09:00 Subject: Re: Passing parameters into a singleton class def? Sean O'halpin wrote: > Something like this? > > class A > end > > a = A.new > fields = [:a, :b] > (class << a; self; end).class_eval do > attr_accessor *fields > end > a.a = 1 > a.b = 2 > p a > b = A.new > b.a = 3 > __END__ > # > rt.rb:13: undefined method `a=' for # (NoMethodError) > > Regards, > Sean David Masover wrote: > 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. Thanks very much to both of you! I'm not using why's metaid gem, but I am familiar with the way he does things. I had tried using class_eval, as Sean suggested, but I wasn't using it quite correctly. Sean's code worked perfectly, but I wanted to make it a little more compartmentalized, so I used some of why's strategy. Here's the final working example code: class MyClass def metaclass class << self self end end ... def add_fields(*field_list) metaclass.class_eval do attr_accessor *field_list end end end Of course, it would be better to move the metaclass method into a mixin, or just use why's metaid gem. Thanks again, Doug -- Posted via http://www.ruby-forum.com/.