Adding an attribute to an object

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.

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
=> #<Dog:0x2063cc>
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
=> #<Dog:0x265afc>
irb(main):008:0> d2.name = "Spike"
=> "Spike"
irb(main):009:0> d2.age = 7
NoMethodError: undefined method `age=' for #<Dog:0x265afc @name="Spike">
  from (irb):9

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
=> #<Dog:0x287eb8>
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

···

On Nov 14, 2007 6:10 PM, Mark Volkmann <r.mark.volkmann@mac.com> wrote:
  from :0

cfp:~ > cat a.rb
require 'attributes' ### gem install attributes

o = Object.new

o.instance_eval{ attribute 'foobar' => 42 }

p o.foobar #=> 42

o.foobar = 'forty-two'

p o.foobar #=> "forty-two"

p o.foobar? #=> "forty-two" (true)

o.foobar 42.0

p o.foobar #=> 42.0

cfp:~ > ruby a.rb
42
"forty-two"
42.0

a @ http://codeforpeople.com/

···

On Nov 14, 2007, at 7: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.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

As Pat pointed out, there are no 'attributes' in Ruby, just methods.
(Those methods may or may not have a 1-to-1 correspondence to instance
variables; that's all the convenience methods like attr_accessor do,
is set up a simple method.)

irb(main):001:0> o = Object.new
=> #<Object:0x1dbbf4>
irb(main):002:0> def o.duration=( seconds )
irb(main):003:1> @length = seconds
irb(main):004:1> end
=> nil
irb(main):005:0> def o.duration; @length; end
=> nil
irb(main):006:0> o.duration = 120
=> 120
irb(main):007:0> puts o.duration
120
=> nil
irb(main):008:0> def o.duration_in_minutes; @length / 60; end
=> nil
irb(main):009:0> puts o.duration_in_minutes
2
=> nil

···

On Nov 14, 7:10 pm, Mark Volkmann <r.mark.volkm...@mac.com> 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?