0

How do you access a Ruby instance variable/method dynamically? I'm basically after the Ruby equivalent of the following PHP code...

$foo = new Foo;
$bar = 'bar';

echo $foo->$bar;
echo $foo->$bar();
chattsm
  • 4,651
  • 5
  • 19
  • 20

3 Answers3

4

The #send method takes a method name. You can call #intern on a string to make a Symbol from it. So this is the equivalent:

foo = Foo.new
bar = 'bar'
puts foo.send(bar.intern)

Instance variables are private by default. To expose them, the normal thing to do is to add a attr_reader call to the class definition:

class Foo
  attr_reader :bar

  def initialize(value_of_bar)
    @bar = value_of_bar
  end
end

bar = 'bar'
foo = Foo.new("bar_value")
puts foo.bar # => "bar_value"
puts foo.send(:bar) # => "bar_value"
puts foo.send(bar.intern) # => "bar_value"

To reach in and access instance variables that don't have reader methods, #instance_variable_get will work, though it's often better to avoid it.

rep
  • 1,546
  • 1
  • 12
  • 19
3
class Foo
  def initialize
    @x = 10
  end
  def test
    @x
  end
end
foo = Foo.new
foo.instance_variables
# => [:@x]
foo.instance_variable_get(:@x)
# => 10
Foo.instance_methods(false)
# => [:test]
Foo.instance_methods(false).map{|i| foo.method(i).call}
# => [10]
Foo.instance_methods(false).map{|i| foo.send(i)}
# => [10]
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
1

instance_variable_get (Don't forget the @).

class Foo
  def initialize
    @ivar = "hello"
  end
end

foo = Foo.new

foo.instance_variable_get :@ivar
#=> "hello"

Alternatively provide an accessor on the class

class Bar
  attr_reader :ivar

  def intialize
    @ivar = "hey"
  end
end

Bar.new.ivar
#=> "hey"
Aaron Cronin
  • 2,093
  • 14
  • 13