Передать параметр по ссылке в 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"}