我正在读一下Ruby中的if / elsif / else,在描述控制表达式如何工作时,我遇到了一些术语上的差异。
在Ruby Programming Wikibooks中(强调添加):
条件分支获取测试表达式的结果并执行代码块,具体取决于测试表达式是true还是false。
和
然而,Ruby-doc.org在定义中根本没有提到块:例如,if表达式不仅可以确定从属代码块是否会执行,而且还会产生值本身。
最简单的if表达式有两个部分,一个是“test”表达式,另一个是“then”表达式。如果“test”表达式的计算结果为true,则评估“then”表达式。
通常,当我读到关于'块'在Ruby中,它几乎总是在procs和lambdas的上下文中。例如,rubylearning.com定义了一个块:
Ruby 块是一种对语句进行分组的方法,可能只出现在与方法调用相邻的源中; 块从与方法调用的最后一个参数(或参数列表的右括号)相同的行开始写入。
问题:
这些问题的上下文:我想知道是否引用条件内部的代码,因为 blocks 会在新的Ruby程序员被引入块,procs和lambdas时混淆。 / p>
答案 0 :(得分:1)
if...end
是表达式,而不是块在Ruby中正确使用术语block
是传递给do...end
或花括号{...}
之间的方法的代码。通过使用方法签名中的Proc
语法,可以并且通常将块隐式转换为方法中的&block
。这个新的Proc
是一个对象,它有自己的方法,可以传递给其他方法,存储在变量和数据结构中,重复调用等等......
def block_to_proc(&block)
prc = block
puts prc
prc.class
end
block_to_proc { 'inside the block' }
# "#<Proc:0x007fa626845a98@(irb):21>"
# => Proc
在上面的代码中,隐式创建Proc
,并将块作为其主体并分配给变量block
。同样,Proc
(或lambda
,Proc
类型可以“扩展”为块,并通过使用&block
传递给期望它们的方法参数列表末尾的语法。
def proc_to_block
result = yield # only the return value of the block can be saved, not the block itself
puts result
result.class
end
block = Proc.new { 'inside the Proc' }
proc_to_block(&block)
# "inside the Proc"
# => String
虽然block
和Proc
之间有一条双向的街道,但它们并不相同。请注意,要定义Proc
,我们必须将block
传递给Proc.new
。严格来说,block
只是传递给方法的一大块代码,该方法的执行延迟到显式调用。 Proc
定义为block
,其执行也会延迟到被调用,但它是一个真实的对象,就像其他任何对象一样。 block
无法自行生存Proc
。
另一方面,block
或block of code
有时会被随意用来指代由end
终止的Ruby关键字所包含的任何谨慎的代码块:if...else...end
,{ {1}},begin...rescue...end
,def...end
,class...end
,module...end
。但这些本身并不是真正的块,只是表面上真的很像它们。通常它们也会延迟执行,直到满足某些条件。但是他们可以完全依靠自己,并且总是有回报价值。 Ruby-doc.org使用“表达式”更准确。
编程语言中的表达式是一个或多个的组合 更明确的值,常量,变量,运算符和函数 编程语言解释(根据其特定 优先权和关联规则)和计算产生(“to 返回“,在有状态的环境中”另一个值。
这就是为什么你可以做这样的事情
until...end
尝试使用块
return_value = if 'expression'
true
end
return_value # => true
块本身不是表达式。它需要return_value = do
true
end
# SyntaxError: (irb):24: syntax error, unexpected keyword_do_block
# return_value = do
# ^
或转换为yield
才能生存。当我们将一个块传递给一个不需要它的方法时会发生什么?
Proc
该块完全丢失,它消失,没有返回值,没有执行,就好像它从未存在过一样。它需要puts("indifferent") { "to blocks" }
# "indifferent"
# => nil
来完成表达式并产生返回值。
yield