brianegge
brianegge

Reputation: 29852

How do I create a reusable block/proc/lambda in Ruby?

I want to create a filter, and be able to apply it to an array or hash. For example:

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

The I want to be able to use it like so:

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

This seems like it should be straight forward, but I can't figure out what I need to do it get it to work.

Upvotes: 54

Views: 25178

Answers (4)

jaredsmith
jaredsmith

Reputation: 7553

If you are using this in an instance, and you do not require any other variables outside of the scope of the proc (other variables in the method you're using the proc in), you can make this a frozen constant like so:

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

Creating a proc in Ruby is a heavy operation (even with the latest improvements), and doing this helps mitigate that in some cases.

Upvotes: 0

Antti Tarvainen
Antti Tarvainen

Reputation: 1219

puts x.select(&method(:isodd))

Upvotes: 31

Daniel Vandersluis
Daniel Vandersluis

Reputation: 94113

You can create a named Proc and pass it to the methods that take blocks:

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

The & operator converts between a Proc/lambda and a block, which is what methods like select expect.

Upvotes: 20

Dave Ray
Dave Ray

Reputation: 40005

Create a lambda and then convert to a block with the & operator:

isodd = lambda { |i| i % 2 == 1 }
[1,2,3,4].select(&isodd)

Upvotes: 77

Related Questions