Frodo Larik <lists / elasto.nl> 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 <<some_instance
end

So you can do:

class MyThing
end
a = MyThing.new
class <<a
  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;self;end.send( :attr_accessor, name )
    self.send("#{name}=", val)
  end
end
a = MyThing.new
a.add_attribute :foo, "hello"
a.foo # returns "hello"

Kind regards

    robert