2009-03-08 5 views
1
def foo 
    "foo" 
end 

alias foo2 foo 
puts "foo2: " + foo2.object_id.to_s 
puts "foo: " + foo.object_id.to_s 

Dans l'exemple ci-dessus, je m'attendais à voir la même sortie object_id pour chaque appel de méthode, car ils font référence à la même méthode. Pourquoi vois-je différents object_id's? Lorsque vous alias une méthode dans Ruby, l'alias ne fait pas référence à l'objet original, pas une copie?aliaser une méthode aboutit à différents objets?

Répondre

2

À partir avec une nouvelle réponse en réponse à vos différents commentaires.

Dans l'exemple de code, vous êtes appelant la méthode, sans la référencer. Vous voulez utiliser

method(:foo) 

pour obtenir réellement la méthode elle-même et non le résultat de son appel.

De même, object_id n'est pas la bonne façon de tester si deux méthodes sont identiques, car method(:foo) renvoie un nouvel objet Method à chaque fois. Pour une analogie qui pourrait le rendre plus clair, si vous ouvriez deux fois le même fichier, vous auriez deux handles de fichiers distincts, même si le fichier sous-jacent était le même. Au lieu de cela, je pense que vous voulez:

method(:foo) == method(:foo2) 

qui, comme vous le verrez si vous l'essayez, retourne true.

+0

Fantastique. Merci beaucoup. –

2

Vous appelez object_id sur l'objet retourné par foo, qui est une chaîne créée dans la méthode et qui sera donc différente à chaque fois. Vous verriez les mêmes résultats si vous appelez simplement foo deux fois. Il renvoie une nouvelle chaîne à chaque fois. Si vous voulez une chaîne constante, renvoyez le symbole :foo à la place. Passé cela, même s'ils partagent la même implémentation en ce moment, sont différentes méthodes. Si vous remplacez foo pour renvoyer la chaîne "barre", foo2 continuera à renvoyer "foo".

+0

Oui. J'appelle object_id sur l'objet retourné par foo. J'avais l'intention d'appeler object_id sur la méthode elle-même, mais je ne suis pas sûr que ce soit possible ou logique. Je voulais montrer que foo et foo2 se réfèrent à la même méthode en utilisant l'object_id pour le révéler. –

1

Essayez:

FOO = "foo" 
def foo 
    FOO 
    end 

alias foo2 foo 
puts "foo2: " + foo2.object_id.to_s 
puts "foo: " + foo.object_id.to_s 

Pour obtenir l'effet que vous êtes désireux. "foo" est une expression et elle est évaluée chaque fois que la fonction est appelée. Pour voir pourquoi il en est, considérez que vous pourriez tout aussi bien écrit:

def foo 
    "It is now #{Time.now}" 
    end 

alias foo2 foo 
puts "foo2: " + foo2.object_id.to_s 
puts "foo: " + foo.object_id.to_s 
+0

Je ne suis pas certain de comprendre pourquoi la constante FOO a pour effet de faire en sorte que les méthodes foo et foo2 se réfèrent au même object_id. Votre exemple produit l'effet attendu, mais je ne suis pas sûr de savoir pourquoi la constante de chaîne est requise. Un alias est un alias, ne devrait-il pas référencer le même objet? –

+0

Je ne comprends pas pourquoi vous mentionnez que "foo" est une expression et pourquoi c'est important pour l'expliquer. Je dois manquer quelque chose ici. Toujours pas comprendre cela. –

+0

Ce que je voulais démontrer, c'est que foo et foo2 se réfèrent au même objet. C'est la seule raison pour laquelle j'ai utilisé la méthode object_id. Je pense que la raison pour laquelle votre exemple fonctionne est parce que vous renvoyez une constante. foo2.object_id et foo.object_id se réfèrent alors au même objet - contrairement à mon exemple. –

Questions connexes