2013-09-21 35 views
1

我正在克里斯派恩的一个问题学会编程书。我用一些实例方法定义了一个类Pet。在类定义之外,我试图构建一个方法,该方法将采用一个字符串和一个Pet类的实例并运行适当的实例方法。Ruby:使用散列来访问实例方法

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 

dispatch方法运行,但是,执行中出现的散列的所有实例的方法,而不是仅仅相当于command之一。它们按照它们在代码中出现的顺序执行,并且在达到dispatches[command]行之前执行。

我在这里做错了什么?

+0

给班上的身体也..所以我们可以跑 –

回答

3

是的,这是正确的行为。

{'feed'  => pet.feed} 

该线以上的意思是“呼叫的方法pet.feed,并使用它的返回值用于分配到键‘进料’”。您必须使用lambdas(或类似的)来创建可以稍后调用的代码块。类似这样的:

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

我不明白,为什么需要'lamda'。 –

+0

啊,我明白了。我非常肯定它在调用每个方法,因为哈希正在被填充,但是完全忘了为什么。变量和对象,像往常一样:)谢谢! – ivan

+0

@ArupRakshit:延期调用 –

1

虽然哈希的创建评估所有方法。我建议如果使用send,你会喜欢的东西端到了解使用方法sendhttp://www.ruby-doc.org/core-2.0.0/Object.html#method-i-send)的:

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

请注意,您将需要调整方法putToBed的名称。

+0

恐怕'send'不会为OP做。如果您查看示例代码,您会看到他正在尝试使用字符串'“放置床”来调用方法。该字符串不是有效的方法名称。显然,这是某种人性化界面的一部分。 –

+0

将“put to bed”转换成“put_to_bed”或“putToBed”(这是一个糟糕的方法名称),我认为很容易... – spickermann

+0

但是''去睡觉'=> pet.put_to_bed '?你如何改变它? :)这就是为什么有映射很好。这样你就不会将实现细节泄露给用户。 –