Name of a variable, at runtime

This seems harder than the usual thing I’ve been tripping on (and
finding answers in the pickaxe or online).

I have an object: human. It has parts: human.hand human.foot.

How can I say this:
fred = human.new
fred.hand = fred.foot = fred. leg = ‘flesh’
fred.knee = ‘plastic’
fred.head = ‘steel’
parts = [hand,foot,leg,knee]
parts.each do |part|
puts "part #{part} is made of " + fred.{part}.to_s
end # with each part

Am I close?

Thanks,
–Colin

Colin S. wrote:

This seems harder than the usual thing I’ve been tripping on (and
finding answers in the pickaxe or online).

I have an object: human. It has parts: human.hand human.foot.

How can I say this:
fred = human.new
fred.hand = fred.foot = fred. leg = ‘flesh’
fred.knee = ‘plastic’
fred.head = ‘steel’
parts = [hand,foot,leg,knee]
parts.each do |part|
puts "part #{part} is made of " + fred.{part}.to_s
end # with each part

Am I close?

Thanks,
–Colin

I think that ‘object.send(method)’ gives you what you want:

class Human
attr_accessor :hand, :foot, :leg, :knee, :head
end

fred = Human.new
fred.hand = fred.foot = fred. leg = ‘flesh’
fred.knee = ‘plastic’
fred.head = ‘steel’
parts = %w[hand foot leg knee]

parts.each do |part|
puts "part #{part} is made of " + fred.send(part)
end

Raul

On Nov 11, 2007, at 10:30 PM, Colin S. wrote:

parts = [hand,foot,leg,knee]
parts.each do |part|
    puts "part #{part} is made of " + fred.{part}.to_s
end # with each part

Am I close?

Close, yes, but not quite there. Assuming you want to roll your own
Human class, then you can do something like:

class Human attr_accessor :hand, :leg, :foot, :head, :knee end

fred = Human.new
fred.hand = fred.foot = fred.leg = ‘flesh’
fred.knee = ‘plastic’
fred.head = ‘steel’
parts = %w[hand foot leg knee]
parts.each do |part|
puts “part #{part} is made of #{fred.send(part)}”
end

OTOH, you might look at the built-in Struct class. It may do
everything you want.

Regards, Morton

Well, technically it will be a Rails object, so I don’t create it,
ActiveRecord does, but I bet the send(part) thing will work. Thanks.
This will make a really LOOOOONG table get generated with a few lines
of code instead.

–Colin

Colin S. wrote:

Well, technically it will be a Rails object, so I don’t create it,
ActiveRecord does, but I bet the send(part) thing will work. Thanks.
This will make a really LOOOOONG table get generated with a few lines
of code instead.

–Colin

In case you wanted an explanation of how things work, take a look at
this example:

class Human
def knee=(str)
@knee = str
end

def knee
return @knee
end

end

fred = Human.new
fred.knee = ‘plastic’
puts fred.knee
—>plastic

When you write:

fred.knee = ‘plastic’

you are actually calling a method–the method named ‘knee=’. In Ruby,
method names can have characters like ‘=’ and ‘?’ in them. When the
method ‘knee=’ is called, the statement in the body of the method is
executed, and that statement assigns a value to the member variable
@knee.

Likewise, when you write:

puts fred.knee

that calls the method named ‘knee’, and the knee method is defined to
return the value of the member variable @knee.

Therefore, the problem you were faced with becomes: how do you call a
method if you have the name of the method as a string. That’s where
Object#send comes in–it allows you to do just that.

Although it wouldn’t make much sense, you could actually define the
knee= method like this:

class Human
def knee=(str)
@head = str
end

def head
return @head
end

end

fred = Human.new
fred.knee = ‘steel’
puts fred.head
—>steel