'передать параметр по ссылке' в Ruby?

В Ruby можно передать по ссылке параметр с семантикой значения-типа (например, Fixnum)? Я ищу что-то похожее на ключевое слово С# ref.

Пример:

def func(x) 
    x += 1
end

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

Btw. Я знаю, что могу просто использовать:

a = func(a)

Ответ 1

Вы можете выполнить это, явно передав текущую привязку:

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

a = 5
func(:a, binding)
puts a # => 6

Ответ 2

Ruby не поддерживает "pass by reference" вообще. Все является объектом, и ссылки на эти объекты всегда передаются по значению. Фактически, в вашем примере вы передаете копию ссылки на объект Fixnum по значению.

Проблема с вашим кодом заключается в том, что x += 1 не изменяет переданный объект Fixnum, а создает новый и независимый объект.

Я думаю, Java-программисты вызывают Fixnum объекты неизменяемые.

Ответ 3

В Ruby вы не можете передавать параметры по ссылке. Для вашего примера вам нужно будет вернуть новое значение и назначить его переменной a или создать новый класс, содержащий значение, и передать экземпляр этого класса. Пример:

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

Ответ 4

Вы можете попробовать следующий трюк:

def func(x) 
    x[0] += 1
end

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

Ответ 6

Однако кажется, что составные объекты, такие как хеши, передаются по ссылке:

fp = {}
def changeit(par)
  par[:abc] = 'cde'
end

changeit(fp)

p fp

дает

{:abc=>"cde"}