Использование лямбды внутри метода Ruby - PullRequest
0 голосов
/ 02 сентября 2018

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

Итак первый шаг имеет этот метод:

def filter (arr)
    arr.each do |e|
        puts e if e % 2 != 0
    end
end 

filter [1, 2, 3, 4, 5, 6]

И ожидаемый результат:

1 3 5 [Завершено за 0,2 с]

Второй Я попробовал это:

def filter (arr)
    arr.each do |e|
        puts e if yield(e)
    end
end 

filter ([1, 2, 3, 4, 5, 6]) { |n| n.odd? }

И я получил тот же результат:

1 3 5 [Завершено за 0,2 с]

Третий Я хочу сделать это с помощью лямбды. В конечном итоге я хочу вызвать метод filter, например, filter([1, 2, 3, 4, 5, 6], &is_odd). Но так как я до сих пор не могу понять это, я сейчас застрял в этом:

is_odd = lambda { |n| puts n if n.odd? }

def filter ()
    arr = [1, 2, 3, 4, 5, 6]
    arr.each do |e|
        is_odd(e)
    end
end 

filter &is_odd

И я получил следующую ошибку:

block in filter': undefined method is_odd 'для main: Object (NoMethodError)

Для меня имеет смысл, что это не работает, поскольку, если я определю лямбду внутри функции filter и использую ее следующим образом:

def filter ()
    is_odd = lambda { |n| puts n if n.odd? }
    arr = [1, 2, 3, 4, 5, 6]
    arr.each &is_odd
end 

filter

Я снова получаю ожидаемое поведение, но я следую учебному пособию, и кажется, что можно объявить is_odd вне метода filter и вызвать фильтр следующим образом: filter([1, 2, 3, 4, 5, 6], &is_odd).

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

1 Ответ

0 голосов
/ 02 сентября 2018

Я хотел бы знать, действительно ли возможно использовать лямбду таким образом

Да.

и если да, то где моя логика потерпела неудачу?

Передавая лямбду как &is_odd, вы превращаете ее в блок метода. Итак, используйте его как блок. В приведенном выше фрагменте вы показываете, что знаете о yield. Вот еще один способ вызова переданного блока.

is_odd = lambda { |n| puts n if n.odd? }

def filter(&block)
    arr = [1, 2, 3, 4, 5, 6]
    arr.each do |e|
        block.call(e)
    end
end 

filter(&is_odd)
# >> 1
# >> 3
# >> 5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...