use*_*677 2 ruby ruby-on-rails ruby-on-rails-5.2
这两者都有效:
Rails.application.credentials.development
Rails.application.credentials.send(:development)
Run Code Online (Sandbox Code Playgroud)
然而,第一个.test有效,但 (:test) 无效。
Rails.application.credentials.test
Rails.application.credentials.send(:test)
Run Code Online (Sandbox Code Playgroud)
为什么 :test 很特别?什么会使这行不通?我明白了
[5] pry(#<Cred>)>Rails.application.credentials.send(:test)
ArgumentError: wrong number of arguments (given 0, expected 2..3)
from (pry):5:in `test'
Run Code Online (Sandbox Code Playgroud)
test是模块中定义的私有方法Kernel。Kernel包含在每个 ruby 对象中。当您调用.send(:test) 此方法时,它会被调用,并且需要 2 或 3 个参数。
它也可以在其他对象上复制:
[15] pry(main)> :a.send(:test)
ArgumentError: wrong number of arguments (given 0, expected 2..3)
from (pry):23:in `test'
[16] pry(main)> 1.send(:test)
ArgumentError: wrong number of arguments (given 0, expected 2..3)
from (pry):24:in `test'
Run Code Online (Sandbox Code Playgroud)
编辑
我不确定 object 是什么credentials,所以我不能肯定地说是这种情况,但是当您定义它时,method_missing它会在直接调用私有方法之前调用,而不是使用send,请参见下文:
class B
def method_missing(*args)
puts args
end
end
pry> B.new.send(:test)
ArgumentError: wrong number of arguments (given 0, expected 2..3)
from (pry):32:in `test'
pry> B.new.test
test
=> nil
Run Code Online (Sandbox Code Playgroud)
编辑2:
一般来说比安全#send #public_send。它不会让你调用私有方法,并且它会被以下方法捕获#method_missing:
[28] pry(main)> B.new.public_send(:test)
test
=> nil
Run Code Online (Sandbox Code Playgroud)