在Ruby中,是if/elsif/else语句';s从属块与a';区块';这是作为参数传递的吗?
我在阅读Ruby中的if/elsif/else,在描述控件表达式如何工作时遇到了一些术语上的差异 在(增加强调部分)中: 条件分支获取测试表达式的结果,并根据测试表达式是真还是假执行代码块 及 例如,if表达式不仅确定是否将执行次级代码块,而且还会生成值本身 然而,Ruby-doc.org在定义中根本没有提到块: 最简单的if表达式有两部分,一个是“test”表达式,另一个是“then”表达式。如果“test”表达式的计算结果为true,则将计算“then”表达式 通常,当我读到Ruby中的“块”时,它几乎总是在procs和lambdas的上下文中。例如,rubylearning.com定义了一个块: Ruby块是对语句进行分组的一种方式,只能出现在与方法调用相邻的源代码中;块从方法调用的最后一个参数(或参数列表的右括号)的同一行开始写入 问题是:在Ruby中,是if/elsif/else语句';s从属块与a';区块';这是作为参数传递的吗?,ruby,terminology,control-flow,Ruby,Terminology,Control Flow,我在阅读Ruby中的if/elsif/else,在描述控件表达式如何工作时遇到了一些术语上的差异 在(增加强调部分)中: 条件分支获取测试表达式的结果,并根据测试表达式是真还是假执行代码块 及 例如,if表达式不仅确定是否将执行次级代码块,而且还会生成值本身 然而,Ruby-doc.org在定义中根本没有提到块: 最简单的if表达式有两部分,一个是“test”表达式,另一个是“then”表达式。如果“test”表达式的计算结果为true,则将计算“then”表达式 通常,当我读到Ruby中的“块
- 当我们谈论Ruby中的代码块时,我们是在谈论 传递给方法的一组代码,或者我们只是 一般来说,谈论一组代码
- 有没有一种方法可以很容易地将两者区分开来 这两者之间的技术区别是什么
如果…end
是表达式而不是块
Ruby中术语block
的正确用法是将代码传递给do…end
或大括号{…}
之间的方法。通过使用方法签名中的&block
语法,一个块可以并且经常在一个方法内隐式地转换为Proc
。这个新的Proc
是一个对象,它有自己的方法,可以传递给其他方法,存储在变量和数据结构中,重复调用,等等
def block_to_proc(&block)
prc = block
puts prc
prc.class
end
block_to_proc { 'inside the block' }
# "#<Proc:0x007fa626845a98@(irb):21>"
# => Proc
虽然在block
s和Proc
s之间有一条双向的街道,但它们并不相同。请注意,要定义Proc
,我们必须将块
传递给Proc.new
。严格地说,块
只是传递给方法的一段代码,其执行延迟到显式调用为止。Proc
是用块定义的,它的执行也会推迟到被调用,但它和其他任何对象一样是真正的对象。块
不能独立生存,而过程
可以
另一方面,block
或block of code
有时被随意用来指任何由以end
结尾的Ruby关键字包围的谨慎的代码块:if…else…end
,begin…rescue…end
,定义…end
,类…end
,模块…end
,直到……结束
。但从本质上来说,这些并不是真正的积木,只是在表面上与它们非常相似。通常,他们也会推迟执行,直到满足某些条件。但它们可以完全独立,并且始终具有返回值。Ruby doc.org对“表达式”的使用更加准确
从
编程语言中的表达式是一个或多个表达式的组合
更明确的值、常量、变量、运算符和函数
编程语言(根据其特定的
优先规则和关联规则)和计算产生(“to
return“,在有状态的环境中)另一个值
这就是为什么你可以这样做
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
来完成表达式并生成返回值
class Object
def puts(*args)
super
yield if block_given?
end
end
puts("mindful") { "of blocks" }
# "mindful"
# => "of blocks"
class Object
def puts(*args)
super
yield if block_given?
end
end
puts("mindful") { "of blocks" }
# "mindful"
# => "of blocks"