[noob] 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 Summers 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

···

--
Posted via http://www.ruby-forum.com/\.

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

<code>
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
</code>

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

Regards, Morton

···

On Nov 11, 2007, at 10:30 PM, Colin Summers 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?

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 Summers 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

···

--
Posted via http://www.ruby-forum.com/\.