参数传递和assert_difference

Parameter passing and assert_difference

我是 Ruby 和 Rails 的新手。我不明白为什么下面的代码(使用了 Rails 教程的 Rails' [ActiveSupport::Testing.assert_difference]1 method) doesn't require a comma after the parameter 1. The code comes from Chapter 7

assert_difference 'User.count', 1 do
  post_via_redirect users_path, ...
end

assert_difference 的签名是:

assert_difference(expression, difference = 1, message = nil, &block)

因此我希望 difference 参数和 block 参数之间需要一个逗号,但显然不是这样。

为什么不需要逗号?

因为您使用特殊的 do |args| ... end/{ |args| ... } 表示法传递块。如果将块作为普通参数传递,则需要逗号:

block = proc { post_via_redirect users_path, ... }
assert_difference 'User.count', 1, &block

块并不是真正的参数 - 方法签名中显示的是此方法捕获在过程中传递给它的块,但这实际上是泄露给外界的实现细节。例如,如果您定义这样的方法

def foo(*args)
end

然后传递给此方法的块不会在 args 中结束。

但是,如果您要传递一个过程(或响应 to_proc 的东西),使用您希望将此参数用作方法块的 & 参数前缀,那么您可以这样做需要逗号。

my_proc = -> {post_via_redirect users_path}
assert_difference User.count, 1, &my_proc

不需要逗号,因为这是 Ruby 语法的工作方式。

块可以通过两种方式传递给方法

1) 使用 do ... end

2) 使用 { ... }

def some_method(&block)
  block.call
end

some_method { 2 + 2 }
#=> 4

some_method do
  2 + 2
end
#=> 4

在控制台中尝试这个示例,您就会理解它们。