2013-09-21 2 views
1

Je travaille sur un problème dans le livre de Chris Pine Learn to Program. J'ai défini une classe Pet, avec quelques méthodes d'instance. En dehors de la définition de la classe, j'essaie de construire une méthode qui prendra une chaîne et une instance de la classe Pet et exécutera la méthode d'instance appropriée.Ruby: utilisation d'un hachage pour accéder à des méthodes d'instance

def dispatch(command, pet) 
    dispatches = {'feed'  => pet.feed, 
       'walk'  => pet.walk, 
       'put to bed' => pet.putToBed, 
       'rock'  => pet.rock, 
       'toss'  => pet.toss} 
    dispatches[command] 
end 

Lorsque la méthode dispatch fonctionne, cependant, il exécute toutes les méthodes d'instance qui apparaissent dans le hachage, pas seulement celle qui correspond à command. Ils s'exécutent dans l'ordre où ils apparaissent dans le code, et avant même d'atteindre la ligne dispatches[command].

Qu'est-ce que je fais mal ici?

+0

donner le corps de la classe aussi .. de sorte que nous puissions exécuter –

Répondre

3

Oui, c'est un comportement correct.

{'feed'  => pet.feed} 

La ligne ci-dessus signifie « méthode d'appel pet.feed et utiliser sa valeur de retour pour affecter à « alimentation » clé ». Vous devez utiliser lambdas (ou similaire) pour créer des morceaux de code qui peuvent être invoqués plus tard. Quelque chose comme ceci:

def dispatch(command, pet) 
    dispatches = {'feed'  => proc { pet.feed }, 
       'put to bed' => proc { pet.put_to_bed }} 
    dispatches[command].call 
end 
+0

Je ne comprends pas, pourquoi il y a un besoin de 'lamda'. –

+0

Ahhh, je vois. J'étais à peu près sûr qu'il appelait chaque méthode comme le hachage était peuplé, mais j'ai oublié exactement pourquoi. Variables et objets, comme d'habitude :) Merci! – ivan

+0

@ArupRakshit: invocation différée –

1

Bien que la création du hachage toutes les méthodes sont évaluées. Je vous conseille de lire sur l'utilisation de la méthode send (http://www.ruby-doc.org/core-2.0.0/Object.html#method-i-send) Si vous utilisez send vous finirez avec quelque chose comme:

def dispatch(command, pet) 
    pet.send(command) 
end 

Notez que vous devrez régler le nom de la méthode putToBed.

+0

J'ai peur, 'envoyer' ne fera pas pour OP. Si vous examinez un exemple de code, vous verrez qu'il essaie d'utiliser la chaîne '" put to bed "' pour appeler une méthode. Cette chaîne n'est pas un nom de méthode valide. Apparemment, cela fait partie d'une sorte d'interface conviviale. –

+0

Il serait facile de transférer "mettre au lit" dans "put_to_bed" ou "putToBed" (ce qui est un mauvais nom de méthode), je pense ... – spickermann

+0

Mais qu'en est-il de '" go to sleep "=> pet.put_to_bed '? Comment transformez-vous cela? :) C'est pourquoi il est bon d'avoir des cartographies.Pour ne pas divulguer les détails de l'implémentation à l'utilisateur. –

Questions connexes