Read the latest web development and design tips at Fred Wu's new blog! :-)
Poke me on GitHub

Variable methods and accessors in Ruby

Yeah I am a lame PHP guy who hasn’t gotten too deeply into Ruby yet. ;)

In PHP I often use variable methods, for example:

$foo = new Foo();

$funcname = 'dynamic_method';
$foo->$funcname();
// Same as calling $foo->dynamic_method();

$varname = 'dynamic_accessor';
$foo->$varname = 'some value';
// Same as calling $foo->dynamic_accessor = 'some value';

Now, because Ruby does not prefix $ in front of variables, it is impossible to use variable methods the way we do in PHP.

I am sure for Ruby gurus it’s pretty obvious but for me, I just spent more than 30 minutes searching for an alternative other than evil eval, and I finally found one.

We use the PHP call_user_func and call_user_func_array equivalent in Ruby: send or __send__.

Luckily accessors in Ruby are methods, so we are able to use the send method for both methods and accessors.

For example we can set a variable accessor like this:

foo = Foo.new

funcname = 'dynamic_method'
foo.send "#{funcname}"
# same as calling foo.dynamic_method

varname = 'dynamic_accessor'
foo.send "#{varname}=", 'some value'
# same as calling foo.dynamic_accessor = 'some value'

I wish in future versions of Ruby, we can somehow assign accessor values the way we do in PHP. :)

  • Digg
  • DZone
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Live
  • Reddit
  • Slashdot
  • StumbleUpon
  • Technorati
  • Twitter

Related posts

Tags: , ,

Comments Section

2 Responses to “Variable methods and accessors in Ruby”

Sidebar might be covered by comments ... consider it a feature! ;)
  1. 1

    I’m a lame ruby guy who has a new project that has to work in php. So I’m the opposite of you. Thanks for the helpful post, although call_user_func isn’t exactly like send because it doesn’t get called on an object.

    I miss some of the ruby blocks (locally defined functions) already.

    If you really wanted the assign accessors on an object for everything, just override method_missing on an object to automatically set a class variable if called with a “something=” method. :)

  2. 2

    This is usually a bad idea – don’t go accessing those private object internals!!

    If you want to make them public, use attr_accessor…


    class Foo
    attr_accessor :dynamic_accessor
    end

    f= Foo.new
    f.dynamic_accessor = 'blah'

    If you really want to go peeking into those private internals, you can use instance_variable_get or set…


    f.instance_variable_set(:some_var, 'some_value')
    # same as inside class Foo doing @some_value

    Check out the RDOC for Object class (every objects parent): http://www.ruby-doc.org/core/classes/Object.html


    # I kind of like 'send' as a method:
    funcname = 'dynamic_method'
    foo.send(funcname) # no need for quotes here

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>