adding an attribute to an object

M

Mark Volkmann

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.
 
P

Pat Maddox

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
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
=> #<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
 
A

ara.t.howard

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.

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"
"forty-two"
42.0


a @ http://codeforpeople.com/
 
P

Phrogz

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?

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,270
Messages
2,571,352
Members
48,034
Latest member
BettinaArn

Latest Threads

Top