我正在查看一些粗略的代码:
foo = true
while foo
foo = newfoo() do
thing1()
end
end
这里发生了什么? do
作业后面的end
... foo
块有什么作用?
答案 0 :(得分:2)
这是一个街区。在Ruby中存在块,proc和lambdas。请查看此链接以更好地了解它。
http://www.reactive.io/tips/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/
答案 1 :(得分:2)
你看到的是...在进行赋值之前将结束块传递给函数。 记住代码:
[1,2].each do puts "xd" end
? 块“do puts”xd“end”在这里传递给“each”方法。
代码相同。
使用块调用newfoo()函数,在newfoo()中可以产生块,然后将newfoo()的返回值赋给foo。
但是你应该避免这种语法,如果块是短使用{}而不是do..end,如果不是 - 请考虑使用Proc.new。
两个代码示例,两者都有相同的结果:
def newfoo()
yield()
return false
end
foo = true
while(foo)
foo = newfoo() do
puts "JP2GMD"
end
end
带存储过程的版本
truth_to_be_spoken = Proc.new { puts "JP2GMD" }
def newfoo()
yield()
return false
end
foo = true
while(foo)
foo = newfoo() {truth_to_be_spoken.call()}
end
编辑以回复评论
“{}”在任何其他情况下肯定不比“do ... end”更好,而不是传递真正的短proc(在例子中就是这种情况)。
为什么你要在实际情况下使用proc而不是传递 result 参数(注意这只是显示语法的例子,而不是现实世界的使用!):原因很多,现在我能想到至少两个简单的例子:
1.只有在需要时,您才可以使用它来懒散地评估函数内部:
magic_number = Proc.new do
x = # some really complicated code
# it posts question on stackoverflow
# to ask users, what number they would like to divide
# waits an hour for answers
# and picks the one with most votes
return x
end
def divide_numbers(divisor)
if divisor == 0
puts "Cannot into"
else
dividend = yield
puts (dividend / divisor)
end
您可以使用函数内部已知的值并将它们作为参数传递(实际上,您使用迭代方法的方式!)。下面是两次使用的代码 - 参数与块“{}”一起传递,而在“{}”中将参数传递给声明的proc:
second_power_double_printer = Proc.new do | param | 把帕拉姆 把帕拉姆 端
[1,2,3,4] .each {| number | double_printer.call(number * number)}
为什么使用do..end / {}语法而不是传递阻止作为参数。 可能有更多的理由我无法想到正确的知识,但
Do ... end / {}将隐式为您创建匿名块。您不能使用参数执行此操作,例如:
def f(proc) proc.call() 端
f(确实说“很难过:(”结束)
如果您使用匿名阻止,您至少可以犯一个错误 - 忘记传递阻止。 如果你使用函数参数,你至少可以犯两个错误 - 忘记传递任何东西(尽管 - 如果你使用IDE它会在这种情况下帮助你)并传递一些东西,这不是一个块 - 导致“未定义的方法调用“错误。