передать параметр по ссылке в Ruby? - PullRequest
26 голосов
/ 02 октября 2008

Можно ли в 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)

Ответы [ 6 ]

31 голосов
/ 02 октября 2008

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

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

a = 5
func(:a, binding)
puts a # => 6
19 голосов
/ 02 октября 2008

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

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

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

11 голосов
/ 02 октября 2008

В 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
6 голосов
/ 02 марта 2015

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

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'
2 голосов
/ 02 марта 2016

http://ruby -doc.org / ядро-2.1.5 / Fixnum.html

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

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

0 голосов
/ 16 мая 2019

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

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

changeit(fp)

p fp

дает

{:abc=>"cde"}
...