如何使用' do'创建一个接受匿名函数的函数?关键字语法?

时间:2014-09-25 20:07:10

标签: ruby syntax higher-order-functions

使用array.each时,您可以用两种形式指定功能:

大括号:

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

输出:

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

'do'语法:

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

输出:

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

问题: 如何使用自己的自定义函数复制'do'语法样式?最接近我可以得到的大括号样式是:

我尝试了什么:

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

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

输出:

102
=> nil

1 个答案:

答案 0 :(得分:5)

do |foo| … end{ |foo| … }语法是等效的。这些是Ruby中的“块”,任何方法都可以获得它们。要打电话给他们,你需要:

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

或者,对于更复杂的用途:

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

当您需要将块传递给另一个方法时,后一种样式很有用。如果您有变量引用的Proc或Lambda,则可以使用&语法将其作为该方法的块传递给方法:

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}    

有关详细信息,this webpage非常有启发性。