3

How can I add new attributes to a particular instance ?

For example here I want to add attr_acessors methods to attributes "m1","m2" in object e1 and "m4".."m6" to e2

e1=Element.new("e1",["m1","m2"])
e2=Element.new("e2",["m4","m5","m6"])
e1.m1 = "try"
puts e2.m4

To allow this :

class Element
  attr_accessor :name
  def initialize name,meths=[]
    @name=name
    meths.each do |m|
      #?? 
    end
  end
end
dbyrne
  • 59,111
  • 13
  • 86
  • 103
JCLL
  • 5,379
  • 5
  • 44
  • 64

3 Answers3

2

Why not use a simple OpenStruct instead?

require 'ostruct'
e1 = OpenStruct.new
e1.m1 = 'try'

Alternatively, you can add attribute to any object using:

a.instance_eval('def m2; @m2; end; def m2=(x); @m2=x;end')

If you want to add attributes to all instances of specific class you can also:

a.class.instance_eval('attr_accessor :mmm')
Gregory Mostizky
  • 7,231
  • 1
  • 26
  • 29
1

Try this:

meths.each do |m|
  singleton_class().class_eval do
    attr_accessor m
  end
end

where the singleton_class() method is defined as:

def singleton_class
  class << self
    self
  end
end

(you probably want to make it private).

This will create the accessors only on the specific instance rather than on the Element class.

Jonathan
  • 3,203
  • 2
  • 23
  • 25
  • Thx Jonathan. That is my favorite solution ! I was struggling with something similar this afternoon. – JCLL Mar 10 '11 at 16:27
1

Here is a simpler solution:

methods.each do |method|
 class << self
  attr_accessor method
 end
end

This way, you get rid of the extra method definition and class_eval because class << self already puts you into the scope of the eigenclass, where you add singleton methods.

Aaa
  • 1,854
  • 12
  • 18