views:

3224

answers:

4

In Ruby, is it possible to pass by reference a parameter with value-type semantics (e.g. a Fixnum)? I'm looking for something similar to C#'s 'ref' keyword.

Example:

def func(x) 
    x += 1
end

a = 5
func(a)  #this should be something like func(ref a)
puts a   #should read '6'

Btw. I know I could just use:

a = func(a)
+7  A: 

Ruby doesn't support "pass by reference" at all. Everything is an object and the references to those objects are always passed by value. Actually, in your example you are passing a copy of the reference to the Fixnum Object by value.

The problem with the your code is, that x += 1 doesn't modify the passed Fixnum Object but instead creates a completely new and independent object.

I think, Java programmers would call Fixnum objects immutable.

Christoph Schiessl
I don't get this thing that Ruby doesn't pass by ref, when variables and parameters can only contain references to objects. Saying that references are passed by value is the same as saying that objects are passed by reference.
Damien Pollet
+4  A: 

You can accomplish this by explicitly passing in the current binding:

def func(x, bdg)
  eval "#{x} += 1", bdg
end

a = 5
func(:a, binding)
puts a # => 6
jmah
+4  A: 

In Ruby you can't pass parameters by reference. For your example, you would have to return the new value and assign it to the variable a or create a new class that contains the value and pass an instance of this class around. Example:

class Container
attr_accessor :value
 def initialize value
   @value = value
 end
end

def func(x)
  x.value += 1
end

a = Container.new(5)
func(a)
puts a.value
muesan
+2  A: 

The bottom of this page shows how to create a more ref-like equivalent: http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc

jmah