Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make a function that accepts an anonymous function using 'do' keyword syntax?

When using array.each you can specify the function in two forms:

Curly Braces:

a = [1,2,3]
a.each { |x| puts x * x }

Output:

1
4
9
=> [1, 2, 3]

'do' Syntax:

a = [1,2,3]
a.each do |x|
    puts (x * x)
end

Output:

1
4
9
=> [1, 2, 3]

Question: How can I replicate the 'do' syntax style with my own custom function? The closest to the curly brace style I can get is:

What I've tried:

def PutWith2Arg(proc)
    puts proc.call(2)
end

PutWith2Arg(Proc.new { |x| x + 100 })

Output:

102
=> nil
like image 876
James Avatar asked Aug 25 '26 03:08

James


1 Answers

The do |foo| … end and { |foo| … } syntaxes are equivalent. These are 'blocks' in Ruby, and any method can get them. To call them you need to either:

def my_method               # No need to declare that the method will get a block
  yield(42) if block_given? # Pass 42 to the block, if supplied
end

my_method do |n|
  puts "#{n} times 2 equals #{n*2}"
end
#=> "42 times 2 equals 84"

my_method{ |n| puts "#{n} times 2 equals #{n*2}" }
#=> "42 times 2 equals 84"

my_method # does nothing because no block was passed

or, for more sophisticated uses:

def my_method( &blk ) # convert the passed block to a Proc named blk
  blk.call( 42 ) if blk
end

# Same results when you call my_method, with or without a block

The latter style is useful when you need to pass the block on to another method. If you have a Proc or Lambda referenced by a variable, you can pass it to a method as the block for that method using the & syntax:

def my_method( &blk )   # convert the passed block to a Proc named blk
  [1,2,3].each( &blk )  # invoke 'each' using the same block passed to me
end
my_method{ |x| p x=>x**2 }
#=> {1=>1}
#=> {2=>4}
#=> {3=>9}    

For more details, this webpage is fairly instructive.

like image 138
Phrogz Avatar answered Aug 27 '26 18:08

Phrogz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!