我没有理解以下行为(另请参见此SO线程):
def def_test
puts 'def_test.in'
yield if block_given?
puts 'def_test.out'
end
def_test do
puts 'def_test ok'
end
block_test = proc do |&block|
puts 'block_test.in'
block.call if block
puts 'block_test.out'
end
block_test.call do
puts 'block_test'
end
proc_test = proc do
puts 'proc_test.in'
yield if block_given?
puts 'proc_test.out'
end
proc_test.call do
puts 'proc_test ok'
end
Run Code Online (Sandbox Code Playgroud)
输出:
def_test.in
def_test ok
def_test.out
block_test.in
block_test ok
block_test.out
proc_test.in
proc_test.out
Run Code Online (Sandbox Code Playgroud)
我不介意明确地声明&block变量并直接调用它,但我更理想地想了解为什么我最终需要它.
block_given?考虑def范围,而不是lambda范围:
def test
l = lambda do
yield if block_given?
end
l.call
end
test { puts "In block" }
Run Code Online (Sandbox Code Playgroud)
这是一个闭包,它似乎从其外部范围lambda捕获了and 块。block_given?这种行为确实有意义,因为该块或多或少是外部方法的隐含参数;如果需要,您甚至可以在命名参数中捕获该块:
def def_test(&block)\n frobnicate &block\nend\nRun Code Online (Sandbox Code Playgroud)\n\n因此,即使没有命名,该块也是参数列表的一部分。
\n\n考虑这段简单的代码:
\n\n\n\ndef f\n lambda do\n puts "\\tbefore block"\n yield if block_given?\n puts "\\tafter block"\n end\nend\n\nputs \'Calling f w/o block\'\nx = f; x.call\nputs\n\nputs \'Calling f w/ block\'\nx = f { puts "\\t\\tf-block" }; x.call\nputs\n\nputs \'Calling f w/o block but x with block\'\nx = f; x.call { puts "\\t\\tx-block" }\nputs\n\nputs \'Calling f w/ block and x with block\'\nx = f { puts "\\t\\tf-block" }; x.call { puts "\\t\\tx-block" }\nRun Code Online (Sandbox Code Playgroud)\n\n对于 1.9.2,这会产生以下结果:
\n\n\n\nCalling f w/o block\n before block\n after block\n\nCalling f w/ block\n before block\n f-block\n after block\n\nCalling f w/o block but x with block\n before block\n after block\n\nCalling f w/ block and x with block\n before block\n f-block\n after block\nRun Code Online (Sandbox Code Playgroud)\n\n此外,Proc#call(又名proc ===)不占用块:
\n\n\nprc === obj \xe2\x86\x92 result_of_proc
\n
\n 调用块,以 obj 作为 block\xe2\x80\x98s 参数。它允许一个proc对象成为case语句中when子句的目标。
将第一行与文档进行比较Enumerable#chunk(例如):
\n\n\n枚举块 {|elt| ... } \xe2\x86\x92 an_enumerator
\n
表示{...}已chunk记录占用块,缺少此类符号表示Proc#call不Proc#call占用块。
这并不完全是一个权威的答案,但也许它能让事情变得更清楚一些。
\n| 归档时间: |
|
| 查看次数: |
763 次 |
| 最近记录: |