这两个Ruby片段不应该以相同的方式工作吗?

时间:2012-03-11 13:28:40

标签: ruby

冒险进入 Ruby ,我开始玩弄像Ruby返回你提到的最后一件事的方式,即使它不是在return构造之后。但是,为什么这两个片段不能以相同的方式工作?不应该吗?

module Enumerable
  def palindrome?
    reversed_self = self.reverse
    self.each_with_index {|el,index|
      unless self[index]==reversed_self[index]
        return false ## <-----
      end
    }
    true
  end
end

到目前为止一切顺利:放['foo','bar','baz']。回文?打印'false'

module Enumerable
  def palindrome?
    reversed_self = self.reverse
    self.each_with_index {|el,index|
      unless self[index]==reversed_self[index]
        false ## <------
      end
    }
    true
  end
end

put ['foo','bar','baz']。回文?由于某种原因打印'true'

这背后的科学是什么?

3 个答案:

答案 0 :(得分:3)

Ruby将返回方法中最后执行的表达式的值。第二个版本中的false不是最后一个表达式,没有任何东西告诉Ruby在该点停止执行,所以它会一直持续到方法结束。

return是一种明确告诉Ruby停止执行并返回值的方法。

答案 1 :(得分:2)

不完全!如my answer here中所述,块内的return与lambda中的return不同。当您从块内部return时,您将从整个方法而不是块中返回。

我们可以说明如下:

return :foo # => LocalJumpError: unexpected return
[1, 2, 3].map { return :foo } # => LocalJumpError: unexpected return
[1, 2, 3].map { :foo } # => [:foo, :foo, :foo]

通常情况下,lambdas不会发生这种情况:

l = lambda { return :foo }
l.call # => :foo
[1, 2, 3].map { l.call } # => [:foo, :foo, :foo]

但是当我们尝试将lambda作为块传递给方法时,行为会改变回来:

[1, 2, 3].map &l # => LocalJumpError: unexpected return

答案 2 :(得分:1)

如果不存在return语句,则函数的返回值是最后计算的值。在第二个剪切中,最后一个值始终为true

第一个代码段以false提前返回。第二个对false没有任何作用,它被丢弃了。