2015-11-05 161 views
2

我在做一些探索。關於Ruby的Ruby的find方法 - 參數?

.find(ifnone = nil) { |obj| block }
方法:從閱讀 documentation,在我看來,你應該能夠傳遞一個方法作爲參數,在沒有指定條件匹配的情況下運行。

它說:

「要求ifnone並指定當它返回其結果,或返回 nil並非如此。」

這似乎與我創建已經返回nil,任何方法的工作說:

 
def message 
puts 'No match.' 
end 
No match. 
=>nil 

如果我使用的是不返回的東西的方法,說:

 
def message 
p 'No match.' 
end 

我會得到:

"No match." 
NoMethodError: undefined method `call' for "No match.":String 

有人會友好地向我解釋,究竟哪種arg /方法實際上應該被傳遞給find方法?謝謝。

回答

2

我很高興你問了這個問題。我從來沒有想過這種方法的find方法,因爲我從來沒有真的必須使用它。我反而總是忽略它,直到你在這裏提到它。根據這篇文章的

http://neverstopbuilding.com/enumerable-find

將傳遞給一個枚舉,像find的說法,將是一個lambda或PROC。如果沒有找到匹配,則不會返回默認的nil,而是返回lambda/proc。

所以一個簡單的例子:

nums = [1, 2, 3, 4] 
nums.find(lambda {raise ArgumentError, "No matches found"}) { |num| num == 5 } 

> ArgumentError: No matches found 

同樣類似地,你可以傳遞一個Proc以及..

nums = [1, 2, 3, 4] 
arg = Proc.new {"No matches found"} 
nums.find(arg) { |num| num == 5 } 

> "No matches found" 

只是一個快速的編輯,你可以在lambda或PROC返回任何值,無論是提出錯誤還是返回值。我想提出一個錯誤,錯誤處理,雖然

+0

我很想忽略這樣的說法了。很高興我們都學到了一些東西!我記得當時看到那篇鏈接的文章,但又找不到它。謝謝:D –

2
NoMethodError: undefined method `call' for "No match.":String 

這是一個很大的提示共同使用。 find想要一個可調用的對象 - 即響應#call的東西。由於Ruby是鴨類型的,所有的這些都可以工作:

def message_method 
    puts "yo" 
end 
...find(method(:message_method)) { ... } 

module MessageModule 
    def self.call 
    puts "yo" 
    end 
end 
...find(MessageModule) { ... } 

class MessageClass 
    def call 
    puts "yo" 
    end 
end 
...find(MessageClass.new) { ... } 

message_proc = Proc.new { puts "yo" } 
...find(message_proc) { ... } 

lambda是構建一個Proc對象的另一種方式;不同的語法使一個有點不同的語義,但問題是lambda將只作爲工作好。)

而一個反常的例子(過時):

require 'continuation' 
callcc do |notfound| 
    ...find(notfound) { ... } 
    ... 
end 
+0

雖然這看起來很徹底,但我更瞭解它。我想我還不夠先進,無法充分利用所有信息。 –

+1

哈哈,對不起。最重要的是,它可以是任何具有「調用」方法的東西。這包括'Proc'和'Method'對象,它們的'call'方法執行它們包裝的代碼。 – Amadan