简体   繁体   中英

Passing :test caused ArgumentError: wrong number of arguments (given 0, expected 2..3)

Both of these work:

Rails.application.credentials.development
Rails.application.credentials.send(:development)

However, the first one, .test works, but (:test) does not.

Rails.application.credentials.test
Rails.application.credentials.send(:test)

Why is :test special? What would make this not work? I get

[5] pry(#<Cred>)>Rails.application.credentials.send(:test)
ArgumentError: wrong number of arguments (given 0, expected 2..3)
from (pry):5:in `test'

test is a private method defined in Kernel module. Kernel is included in every ruby object. When you call .send(:test) this method is invoked and it requires 2 or 3 arguments.

It can be reproduced on other objects as well:

[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'

EDIT

I'm not sure what object is credentials , so I can't say it's the case for sure, but when you define method_missing it's invoked before private methods called directly, but not with send , see below:

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

EDIT2:

In general safer than #send #public_send . It won't let you call a private method and also it's caught by #method_missing :

[28] pry(main)> B.new.public_send(:test)
test
=> nil

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM