5

How can I change the contents of a variable using a method? Maybe I'm not saying this correctly. What is a way to get the reference to a variable like in C? Example:

// main stuff
int gorilla = 29;
makeMeABanana(&gorilla);

void makeMeABanana(int *gorilla) { }

How can I do something like this in Ruby?

isomorphismes
  • 8,233
  • 9
  • 59
  • 70
Imnotanerd
  • 1,167
  • 2
  • 14
  • 30
  • Why? Not sure what you're trying to accomplish here. Ruby and C behave quite differently in this regard—there's no such thing as a void function in Ruby, for example—a more concrete example would really help. – dnch May 05 '11 at 23:02

3 Answers3

5

You should not do this - you're just porting techniques that are fully appropriate to C to Ruby, where they are no longer appropriate. There are several fancy ways around this (eg using a Proc closed over your calling namespace, or eval) but they are usually inappropriate in Ruby unless you know precisely what you're doing.

Peter
  • 127,331
  • 53
  • 180
  • 211
  • Peter, Good answer. Do you think that an example or two of the Ruby way would be good? Returning the new value springs to mind. – Wayne Conrad May 05 '11 at 23:04
2

Recently on the ruby-talk mailing list, someone asked about writing a swap function where swap(a,b) would swap the values of the variables "a" and "b". Normally this cannot be done in Ruby because the swap function would have no reference to the binding of the calling function.

However, if we explictly pass in the binding, then it is possible to write a swap-like function. Here is a simple attempt:

 def swap(var_a, var_b, vars)
    old_a = eval var_a, vars
    old_b = eval var_b, vars
    eval "#{var_a} = #{old_b}", vars
    eval "#{var_b} = #{old_a}", vars
  end

  a = 22
  b = 33
  swap ("a", "b", binding)
  p a                          # => 33
  p b                          # => 22

This actually works! But it has one big drawback. The old values of "a" and "b" are interpolated into a string. As long as the old values are simple literals (e.g. integers or strings), then the last two eval statements will look like: eval "a = 33", vars". But if the old values are complex objects, then the eval would look like eval "a = #", vars. Oops, this will fail for any value that can not survive a round trip to a string and back.

Referred from : http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc

Shaunak
  • 17,377
  • 5
  • 53
  • 84
0

Integers are objects, with an id, like everything else in Ruby. They are implemented like this:

p (0..10).map{|n| n.object_id}
#=>[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]

All other objects have even object_id numbers. There is no way to change 7 (object_id 15) into something else.

steenslag
  • 79,051
  • 16
  • 138
  • 171