ruby-on-rails - 从提供给 instance_exec 的 block 中提前返回

标签 ruby-on-rails ruby return

我需要允许在类的范围内定义和调用 block ,使用 instance_exec (通过 Rails 2.3.2)。然而,在某些情况下,其中一些 block 需要提前返回,这给我带来了问题。

我的应用程序是使用 ruby​​ 1.8.6 构建的,但我也需要让它在 1.8.7 上运行。似乎在这两个版本之间,从 lambda 中返回的能力被删除了。以下适用于 1.8.6,但抛出 LocalJumpError 1.8.7 中的(意外返回):

class Foo
  def square(n)
    n ** 2
  end

  def cube(n)
    n ** 3
  end

  def call_block(*args, &block)
    instance_exec *args, &block
  end
end

block = lambda { |n|
  return square(n) if n < 5
  cube(n)
}

f = Foo.new
f.call_block(5, &block) # returns 125
f.call_block(3, &block) # returns 9 in 1.8.6, throws a LocalJumpError in 1.8.7

我确定,如果我替换 return,我可以让它在 1.8.7 中工作在我的街区 next ,但是 next square(n) if n < 5结果 nil在 1.8.6 中。

有什么方法可以使它在 1.8.6 和 1.8.7 中都能正常工作?我知道我可以重组我的 block 以使用分支而不是提前返回,但有些 block 更复杂并且有多种情况需要提前返回。

此外,如果我想让我的代码在 ruby​​ 1.9 中运行,这是否会进一步改变?

编辑: 我发现它在 1.8.6 而不是 1.8.7 中工作的原因是 1.8.7 定义了它自己的 instance_exec在 C 源代码中,而 1.8.6 使用 Rails 的实现。如果我覆盖 instance_exec在 1.8.7 和 Rails 的版本中,它也可以在那里工作。

最佳答案

评论后编辑 看这个post了解详情。

class Foo

  def square(n)
    n ** 2
  end

  def cube(n)
    n ** 3
  end

  def call_block(*args, &block)
      instance_exec *args, &block
    end
end




def a
  block = lambda { | n|
    return square(n) if n < 5
    cube(n)
  }
 f = Foo.new 
puts f.call_block(3, &block) # returns 125
puts "Never makes it here in 1.8.7"
puts f.call_block(5, &block) # returns 9 in 1.8.6, returns nothing in 1.8.7
end

a

此代码没有任何结果,因为它在 puts 语句之外返回。

proc 和 lambda 的工作方式在 1.9 中发生了变化。所以这有助于解释发生了什么。

原创

我重构了您的代码,它在所有 3 个虚拟机下都能正常工作。有趣的是,您的代码确实在 1.9 下无一异常(exception)地执行。

class Foo

  def square(n)
    n ** 2
  end

  def cube(n)
    n ** 3
  end

  def call_block(*args, &block)
    block.call(self, *args)
  end
end

block = lambda { |obj, n|
  return obj.square(n) if n < 5
  obj.cube(n)
}

f = Foo.new
puts f.call_block(5, &block) # returns 125
puts f.call_block(3, &block) # returns 9

post可能会有一些见解。

关于ruby-on-rails - 从提供给 instance_exec 的 block 中提前返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1711577/

相关文章:

ruby - rake "already initialized constant WFKV_"警告

ruby-on-rails - M.Hartl 的 Ruby on Rails 教程(第 3 版)第 10 章 (10.54) 中的密码重置测试失败

ruby-on-rails - 如何运行特定版本的 ruby​​ gem

ruby-on-rails - Mailcatcher 无法在临时服务器中工作

javascript - 如何设置 JS 在后台运行而不引人注目?

javascript - Ace 编辑器(表单)- 我可以保留换行符/文本格式吗?

javascript - Console.log 和函数返回 (Javascript)

javascript - 如何从 Javascript 中的连续函数返回 boolean 值?

Go:从 defer 中返回

ruby-on-rails - 如何在 Rails 中使用 JSON 填充我的数据库?