加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何在ruby中创建具有给定绑定的块?

发布时间:2020-12-17 02:11:31 所属栏目:百科 来源:网络整理
导读:我正在尝试编写一个将接受哈希作为参数的assert_difference版本,以便代替编写 assert_difference 'thing1',1 do assert_difference ['thing2a','thing2b'],2 do assert_difference 'thing3',-3 do # some triple-indented code end endend 我可以写 assert_d
我正在尝试编写一个将接受哈希作为参数的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在评估表达式时使用了块的绑定.我想要做的是创建一个带有原始绑定的新块 – 类似于:

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

但我没有看到用当前绑定以外的任何东西创建新块的方法.如何使用给定的绑定创建块?

解决方法

也许我错过了一些东西,但我认为你正在尝试使用非常复杂的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

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

编辑:

在创建具有自定义绑定的块时,答案是:否.但是,您可以使用不同的绑定调用代码块,或者使用绑定方法捕获,或者仅通过提供与其绑定相关的对象.

您可以为此目的使用eval(它接受Binding对象作为第二个参数)或更好的instance_eval,class_eval,instance_exec和class_exec.你可以在Jay Fields’ Thoughts blog entry开始挖掘.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读