From: Robert Klemme Date: 2005-08-29T00:21:22+09:00 Subject: Re: Dynamic methods / accessors Robert Klemme wrote: > Frodo Larik wrote: >> Hi all, >> >> I'm trying to setup some kind of dynamic method / accessor assignment >> to objects. But I don't want the other objects from the same class to >> know about "personal" methods. I'm just learning Ruby, so it could be >> I'm missing some crucial knowledge. >> >> For example: >> >> class MyThing >> def create_method(method) >> # I found two things on internet which can acchieve this >> # self.class.class_eval { attr_accessor method } >> # AND >> # self.class.send(:define_method, method, &block) >> # but I'm not sure which is the best one to use, but I think >> # I prefer the attr_accessor, because that's the functionality >> # I need >> end >> end >> >> >> # Create first object >> a = MyThing.new >> a.create_method('box') # Adds a method box to a >> a.box = 'something inside' >> >> # The nicest thing would be if I could do something like this: >> a.create_method('box','some_value'), so a.box is populated with 'some >> value' >> >> # Create second object >> b = MyThing.new >> >> # I don't want the following to happen >> b.box = 'something other' >> >> I don't want the method 'box' be available to b, only to a >> >> How can I achieve this? > You need so called singleton methods. These are present in just a > single instance. You define them via the singleton class. > (Disclaimer: there has been some debate about the naming of these > because "singleton" can be misleading here, but AFAIK this is still > the officiel term.) You access the singleton class (a class that is > associated with a single instance only) like this > > class < end > > So you can do: > > class MyThing > end > a = MyThing.new > class < attr_accessor :box > end > a.box = 'something inside' > > If you want to have it a bit more convenient you can pack this into a > method like this: > > class MyThing > def add_attribute(name, val=nil) > class < self.send("#{name}=", val) > end > end > a = MyThing.new > a.add_attribute :foo, "hello" > a.foo # returns "hello" > > Kind regards > > robert PS: There is also OpenStruct which adds methods on the fly. So you can directly do o = OpenStruct.new o.bar = 10 Kind regards robert