Как мне создать повторно используемый блок / proc / lambda в Ruby? - PullRequest
49 голосов
/ 28 августа 2009

Я хочу создать фильтр и иметь возможность применять его к массиву или хешу. Например:

def isodd(i)
  i % 2 == 1
end

Я хочу иметь возможность использовать его так:

x = [1,2,3,4]
puts x.select(isodd)
x.delete_if(isodd)
puts x

Кажется, это должно быть прямо, но я не могу понять, что мне нужно сделать, чтобы заставить его работать.

Ответы [ 4 ]

73 голосов
/ 28 августа 2009

Создайте лямбду, а затем преобразуйте в блок с помощью оператора &:

isodd = lambda { |i| i % 2 == 1 }
[1,2,3,4].select(&isodd)
31 голосов
/ 28 августа 2009
puts x.select(&method(:isodd))
20 голосов
/ 28 августа 2009

Вы можете создать именованное Proc и передать его методам, которые принимают блоки:

isodd = Proc.new { |i| i % 2 == 1 }
x = [1,2,3,4]
x.select(&isodd) # returns [1,3]

Оператор & преобразует между Proc / lambda и блоком, что и ожидают методы типа select.

0 голосов
/ 09 мая 2019

Если вы используете это в экземпляре, и вам не нужны никакие другие переменные вне области действия proc (другие переменные в методе, в котором вы используете proc), вы можете сделать это замороженной константой так:

ISODD = -> (i) { i % 2 == 1 }.freeze
x = [1,2,3,4]
x.select(&ISODD)

Создание процедуры в Ruby - сложная операция (даже с последними улучшениями), и в некоторых случаях это помогает смягчить это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...