2015-11-05 2 views
2

Я немного разбираюсь. Что касается метода Ruby's Метод поиска Ruby - аргумент?

.find(ifnone = nil) { |obj| block }
: от чтения documentation мне кажется, что вы должны иметь возможность передать метод в качестве аргумента, который будет выполняться в случае, если совпадений для указанных условий нет.

Он говорит:

"называет ifnone и возвращает результат, если он указан, или возвращает 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 

Кто-нибудь будет достаточно любезен, чтобы объяснить мне, какой именно аргумент/метод фактически должен быть передан методу поиска здесь? Благодарю.

ответ

2

Я рад, что вы задали этот вопрос. Я никогда не думал об этом аргументе для метода find, потому что мне никогда не приходилось использовать его раньше. Вместо этого я всегда игнорировал его, пока вы не упомянули об этом здесь.

На основании этой статьи: http://neverstopbuilding.com/enumerable-find

Аргумент вы передаете в перечислимого, как find, будет лямбда или прок. Вместо того, чтобы возвращать значение по умолчанию 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" 

Просто быстро редактировать, вы можете вернуть любое значение в лямбда или прок , будь то повышение ошибки или возврат значения. Я полагаю, поднимая ошибку и обработка ошибок является совместным использованием хотя

+0

Я был соблазн игнорировать этот аргумент тоже. Рад, что мы оба что-то узнали! Я помню, что видел связанную статью некоторое время назад, но не смог найти ее снова. Спасибо: D –

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

Это большой намек. find хочет объект, подлежащий вызову, т. Е. Что-то, что отвечает #call. Поскольку Руби утка типизированный, все это будет работать:

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

Ха-ха, извините. Главное отнять это - это может быть все, что имеет метод 'call'. Сюда входят объекты 'Proc' и' Method', метод 'call' выполняет код, который они обертывают. – Amadan

Смежные вопросы