2013-09-21 32 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 '?你如何改變它? :)這就是爲什麼有映射很好。這樣你就不會將實現細節泄露給用戶。 –