簡體   English   中英

在Ruby中的方法調用中從塊范圍訪問變量

[英]Access variable from the block's scope inside a method call in Ruby

我正在嘗試創建一個與Rails assert_difference類似的最小測試斷言,但是它會檢查是否有任何差異,而不僅僅是數字差異。

這是我當前的實現:

Minitest::Assertions.module_eval do

  def assert_changed(expression, &block)
    unless expression.respond_to?(:call)
      expression = lambda{ eval(expression, block.binding) }
    end
    old = expression.call
    block.call
    refute_equal old, expression.call
  end

end

現在在我的測試套件中,通過執行以下操作來調用它:

# this is working 
username = 'Jim'
assert_changed lambda{ username } do
  username = 'Bob'
end

# this is not working
username = 'Jim'
assert_changed 'username' do
  username = 'Bob'
end

使用lambda(或proc)對assert_changed的第一個調用工作得很好。 使用具有變量名的字符串的第二個調用不起作用。

當它expression = lambda{ eval(expression, block.binding) }以下行時: expression = lambda{ eval(expression, block.binding) }我不斷收到錯誤TypeError: no implicit conversion of Proc into String 有人可以告訴我如何使它工作嗎?

注意:我從Rails assert_difference方法獲得了eval(expression, block.binding)想法。

當它expression = lambda{ eval(expression, block.binding) }以下行時: expression = lambda{ eval(expression, block.binding) }我不斷收到錯誤TypeError: no implicit conversion of Proc into String

我可以肯定地確定,碰到該行時不會出現該錯誤,而是碰到這一行時:

old = expression.call

因此,異常不是由分配觸發的,而是稍后call Proc並執行eval時觸發的。

此時,它將調用存儲在expressionProc 存儲在expressionProc如下所示:

eval(expression, block.binding)

Kernel#eval的第一個參數必須是可以隱式轉換為String (即,響應to_str ),但是它是Proc 如此,您會收到TypeError

進行此工作的最簡單方法可能是重命名變量:

new_expression = expression
unless expression.respond_to?(:call)
  new_expression = lambda{ eval(expression, block.binding) }
end
old = new_expression.call
block.call
refute_equal old, new_expression.call

就個人而言,我可能會這樣寫:

module Minitest::Assertions
  def assert_changed(expression, &block)
    new_expression = if expression.respond_to?(:call)
      expression
    else
      -> { block.binding.eval(expression) }
    end

    old = new_expression.()
    block.()

    refute_equal old, new_expression.()
  end
end

沒有(無用的) Module#module_eval ,並使用call運算符語法和-> stabby lambda文字語法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM