3

I want to store and retrieve some variables from object. For example in a

a = "a"

So far I found two possible ways to do it.

  • Using instance_variable_set and instance_variable_get

    a.instance_variable_set(:@x, 10)
    a.instance_variable_get(:@x) # => 10
    
  • or just using instance_eval

    a.instance_eval { @y = 5 }
    a.instance_eval { @y } # => 5
    

The second approach looks shorter and simpler for me, is there anything wrong with my code if I prefer this one?

evfwcqcg
  • 15,755
  • 15
  • 55
  • 72

2 Answers2

5

Speed isn't everything, but... the instance_variable_set method is faster than using instance_eval. Here's a benchmark if you're interested: https://gist.github.com/1268188

Here's another post that gives another good reason for avoiding instance_eval when possible: Alex Kliuchnikau on instance_eval

Community
  • 1
  • 1
Josh Voigts
  • 4,114
  • 1
  • 18
  • 43
2

If there is no good reason (e.g. metaprogramming), you'd better avoid using instance_variable_get(set), coz it will break encapsulation. You can refer to ruby-doc: thereby frustrating the efforts of the class’s author to attempt to provide proper encapsulation.

And the best practice of using instance_eval is to compose DSL style:

assume you have a Engineer class with instance method: program, play and sleep. So,

sb = Engineer.new

sb.program
sb.play
sb.sleep

# is equivalent to
sb.instance_eval do
  program
  play
  sleep
end

In this case, it's shorter :)

Jing Li
  • 14,547
  • 7
  • 57
  • 69
  • In general, if there is an accessor provided by the class, just use plain getter and setter is better (at least never a bad idea). – Jing Li Aug 31 '12 at 14:59