From: Pat Maddox Date: 2007-11-15T11:26:18+09:00 Subject: Re: adding an attribute to an object On Nov 14, 2007 6:10 PM, Mark Volkmann wrote: > I know how to add new methods to an existing object, but is there a way to add an attribute? > I know I can do it if the object was created with ObjectStruct, but what if it is a "normal" Ruby object? > > R. Mark Volkmann > Object Computing, Inc. > > Not quite sure what you mean...but anyway, maybe this irb session will help you along: irb(main):001:0> class Dog; end => nil irb(main):002:0> d = Dog.new => # irb(main):003:0> Dog.class_eval { attr_accessor :name } => nil irb(main):004:0> d.name = "Fido" => "Fido" irb(main):005:0> (class << d; self; end).class_eval { attr_accessor :age } => nil irb(main):006:0> d.age = 12 => 12 irb(main):007:0> d2 = Dog.new => # irb(main):008:0> d2.name = "Spike" => "Spike" irb(main):009:0> d2.age = 7 NoMethodError: undefined method `age=' for # from (irb):9 from :0 First we call attr_accessor for Dog, which defines #name and #name= for all dogs. Then we define #age and #age= for only the one dog, by calling attr_accessor on that object's singleton class. However, there's not really a concept of "attributes" in Ruby (afaik). attr_* are just macros that define methods that look like class Dog def age=(val) @age = val end def age @age end end You can also dig in to an object with instance_eval and do your work: irb(main):001:0> class Dog irb(main):002:1> attr_reader :name irb(main):003:1> end => nil irb(main):004:0> d = Dog.new => # irb(main):005:0> d.name => nil irb(main):006:0> d.instance_eval { @name = "Spot" } => "Spot" irb(main):007:0> d.name => "Spot" hth Pat