Bug #17596
closedCalling parameters on `new` method results in :rest and -1 arity
Description
Consider the following class:
class Testing
def initialize(a, b, c)
# ...
end
end
...and the following call:
m = Testing.method(:new)
p arity: m.arity, params: m.parameters
Expected
{ arity: 3, params: [[:req, :a], [:req, :b], [:req, :c]] }
Actual
{ arity: -1, params: [[:rest]] }
This is confusing to me as I would expect to be able to see the parameters of the new
method like this. The same applies for `initialize.
I was experimenting with pattern matching interfaces and dynamically defining class constructor definitions as such:
def deconstruct
method(:new).parameters.map { public_send(_1.last) }
end
While this case is not 100% safe for all initializers I had expected it to work for testing and was surprised when it did not.
I've tested and confirmed this behavior back to 2.5 and tested no further back
Updated by baweaver (Brandon Weaver) about 3 years ago
It should be noted that this happens with new
and initialize
both
Updated by soutaro (Soutaro Matsumoto) about 3 years ago
Hi Brandon,
It is because Testing.new
is Class#new
, which accepts any arguments and forward to Testing#initialize
. (I'm not sure if we can change the behavior.)
A workaround would be using instance_method(:initialize)
.
Testing.method(:new).owner # => Class
Testing.method(:initialize).owner # => Class
Testing.instance_method(:initialize).owner # => Testing
Updated by baweaver (Brandon Weaver) about 3 years ago
Ah, this makes some sense, and I'd just seen something similar on Twitter. I would think that one of initialize
or new
would not do that instead of forwarding.
Updated by nobu (Nobuyoshi Nakada) about 3 years ago
- Status changed from Open to Rejected
Class method new
and instance method initialize
are different things.