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

Можно ли в Ruby передавать по ссылке параметр с семантикой типа значения (например, Fixnum)? Я ищу что-то похожее на ключевое слово C# '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)

5 ответов

Решение

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

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

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

Ruby вообще не поддерживает передачу по ссылке. Все является объектом, и ссылки на эти объекты всегда передаются по значению. На самом деле, в вашем примере вы передаете копию ссылки на Fixnum Объект по значению.

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

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

В 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

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

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'

http://ruby-doc.org/core-2.1.5/Fixnum.html

Объекты Fixnum имеют непосредственное значение. Это означает, что когда они назначаются или передаются в качестве параметров, передается фактический объект, а не ссылка на этот объект.

Также Ruby передается по значению.

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

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

changeit(fp)

p fp

дает

{:abc=>"cde"}
Другие вопросы по тегам