ruby - 如何在 ruby​​ 中创建具有给定绑定(bind)的 block ?

标签 ruby binding block

我正在尝试编写一个 assert_difference 版本,它将接受哈希作为参数,这样就不用编写

assert_difference 'thing1', 1 do
  assert_difference ['thing2a', 'thing2b'], 2 do
    assert_difference 'thing3', -3 do
      # some triple-indented code
    end
  end
end

我会写

assert_difference 'thing1' => 1, ['thing2a', 'thing2b'] => 2, 'thing3' => 3 do
  # some single-indented code
end

我已经做到了

def assert_difference_with_hash_support(expression, difference = 1, message = nil, &block)
  if expression.is_a? Hash
    expression.each do |expr, diff|
      block = lambda do
        assert_difference_without_hash_support expr, diff, &block
      end
    end
    block.call
  else
    assert_difference_without_hash_support(expression, difference, message, &block)
  end
end
alias_method_chain :assert_difference, :hash_support

但这不起作用,因为 assert_difference 在计算表达式时使用 block 的绑定(bind)。我想做的是用原始绑定(bind)创建一个新 block ——像这样:

    b = block.send :binding
    expression.each do |expr, diff|
      block = lambda(b) do
        assert_difference_without_hash_support expr, diff, &block
      end
    end
    block.call

但我还没有看到用当前绑定(bind)以外的任何东西创建新 block 的方法。如何创建具有给定绑定(bind)的 block ?

最佳答案

也许我遗漏了什么,但我认为您正在尝试使用 ruby​​ 的非常复杂的功能,而它们对于解决您的问题是不必要的。

我的解决方案是:

def assert_hash(hash, &block)
  if hash.length > 1
    assert_difference(*hash.shift) do
      assert_hash(hash, &block)
    end
  else
    assert_difference(*hash.first, &block)
  end
end

当然它缺少别名,但这不是重点。

编辑:

关于创建带有自定义绑定(bind)的 block ,答案是:不。但是您可以调用具有不同绑定(bind)的代码块,或者使用 binding 方法捕获,或者仅通过提供与其相关的绑定(bind)的对象。

您可以为此目的使用 eval(它接受 Binding 对象作为第二个参数)或更好的 instance_evalclass_evalinstance_execclass_exec。您可以在 Jay Fields' Thoughts blog entry 开始挖掘.

关于ruby - 如何在 ruby​​ 中创建具有给定绑定(bind)的 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6622197/

相关文章:

ruby-on-rails - Rails 应用程序和聊天

Ruby 方法调用层次结构

ios - 滚动后 API 回调中 Tableview 单元格数据发生更改

ios - 定义 block 时未知类型名称 'NSString'

ruby-on-rails - 如何找到@[XX :XXXX] in a string and then find the surrounding text? 的所有实例

Ruby Select 方法(用于数组)问题

silverlight - 在 Silverlight 中,如何根据在列表框中选择的项目设置启用按钮的启用状态?

html - Angular 中组件的字符串@Input 属性的属性绑定(bind)与属性绑定(bind)?

c# - TextBox 不遵守 Get 返回的值

ios - 退出 View Controller 后不要调用回调 block