Ruby的“begin … end”是否有意想不到的后果,而没有“rescue”用作代码块?

我偶尔会看到在ruby中使用的最终块,没有任何的救援,否则,确保等等.例如:
foo = begin
   whatever = 3
   "great"
   42
end

编码器的意图似乎是使用begin … end块仅用于其块分组质量(就好像开始做的那样).就个人而言,我认为这种使用方式违反了最不出意料的原则(开始意味着对我进行异常处理).

以这种方式使用begin … end有任何意想不到的后果吗?开始…结束块有任何语义差异(可能在异常处理?),这使得这种使用危险?

Ruby的语法是令人难以置信的微妙的,如果有奇怪的陷阱等待在这里,我不会感到惊讶.

解决方法

我有时候使用这个东西,如果我想给某个变量分配一些东西,但是我必须首先计算我想要分配的值.它使代码更加整洁这样.我认为这是用户偏好.基本上你在说:我给foo分配一些东西,但为了获得我想要的价值,我首先需要做一些事情.在进行备忘时特别有用,而不是
if @cache.nil?
  do_something!
  @cache = read_value
end

你可以做

@cache ||= begin
  do_something!
  read_value
end

在这里使用的优点是Ruby解释器有一个堆栈,每个表达式通常会在堆栈中推送一些东西,或者从堆栈中取出一些东西.分配只是从堆栈中取得最后一件事,并分配(在这种情况下是最后一行从开始/结束).很多时候知道这一点(Ruby中的堆栈方法)可以是有用的.

我不认为它不是最小的惊喜,但我认为这是用户喜好,而不是要使用它.

您可以看到它不会通过查看Ruby MRI 1.9中生成的字节码指令来做什么意外事件:

RubyVM::InstructionSequence::compile("c = begin; a = 5; 6; end").to_a

 [:trace,1],[:trace,[:putobject,5],[:setlocal,2],6],[:dup],3],[:leave]

跟踪只是堆栈跟踪,你可以忽略它. Dup重复堆栈上的最后一个项目.在本示例中,局部变量a的数量为2,局部变量c的数量为3(因此,putobject,2将分配给变量a等).这与a = 5相比唯一的副作用; c = 6是dup指令,这意味着您的方法的堆栈大小将大于1个插槽.但是这并不是特别重要,因为它只有解释器在这个特定的方法中才有效果,而且堆栈的内存是预先保留的,所以这只意味着堆栈指针将比其它方式递减1.所以基本上没有变化.即使是优化也可能会消失.

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...