Question

En Ruby, est-il possible de passer par référence un paramètre avec une sémantique de type valeur (par exemple, un Fixnum)? Je recherche quelque chose de similaire au mot clé ' ref ' de C #.

Exemple:

def func(x) 
    x += 1
end

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

Btw. Je sais que je pourrais simplement utiliser:

a = func(a)
Était-ce utile?

La solution

Vous pouvez y parvenir en transmettant explicitement la liaison actuelle:

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

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

Autres conseils

Ruby ne prend pas en charge "passage par référence". du tout. Tout est un objet et les références à ces objets sont toujours passées par valeur. En fait, dans votre exemple, vous transmettez une copie de la référence à Fixnum Objet par valeur.

Le problème avec votre code est que x + = 1 ne modifie pas l'objet Fixnum transmis, mais crée plutôt un objet entièrement nouveau et indépendant.

Je pense que les programmeurs Java appellent les objets Fixnum immuables .

En Ruby, vous ne pouvez pas transmettre de paramètres par référence. Pour votre exemple, vous devez renvoyer la nouvelle valeur et l'affecter à la variable a ou créer une nouvelle classe contenant la valeur et transmettre une instance de cette classe. Exemple:

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

Vous pouvez essayer le truc suivant:

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

  

Les objets Fixnum ont une valeur immédiate. Cela signifie que quand ils sont assignés ou   passé en tant que paramètres, l'objet réel est passé, plutôt qu'une référence à   cet objet.

Ruby est analysé par valeur .

Cependant, il semble que les objets composites, comme les hachages, soient passés par référence:

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

changeit(fp)

p fp

donne

{:abc=>"cde"}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top