«передать параметр по ссылке» в Ruby?
-
03-07-2019 - |
Вопрос
В Ruby можно ли передать по ссылке параметр с семантикой типа значения (например,фикснум)?Я ищу что-то похожее на C# 'ссылка'ключевое слово.
Пример:
def func(x)
x += 1
end
a = 5
func(a) #this should be something like func(ref a)
puts a #should read '6'
Кстати.Я знаю, что мог бы просто использовать:
a = func(a)
Решение
Это можно сделать, явно передав текущую привязку:
def func(x, bdg)
eval "#{x} += 1", bdg
end
a = 5
func(:a, binding)
puts a # => 6
Другие советы
Ruby вообще не поддерживает передачу по ссылке.Все является объектом, и ссылки на эти объекты всегда передаются по значению.Фактически, в вашем примере вы передаете копию ссылки на Fixnum
Объект по значению.
Проблема с вашим кодом в том, что x += 1
не изменяет переданное Fixnum
Object, но вместо этого создает совершенно новый и независимый объект.
Я думаю, 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"}