Feature #11491
closedAdd descriptive methods to Method & UnboundMethod
Description
(Using Ruby Version 2.2.2)
I would like Method and Unbound Method to provide methods to provide the following additional information:
-
Method#instance_method?
andUnboundMethod#instance_method?
to indicate whether the method is an instance or a class method -
UnboundMethod#receiver
to provide the type required to be passed toUnboundMethod#bind
I believe this information is already probably readily available, because it can be gleaned from Method#to_s
and UnboundMethod#to_s
. For example:
> String.instance_method(:taint)
=> #<UnboundMethod: String(Kernel)#taint>
The above output tells us the eligible receiver type is String, the owner is Kernel, the "#" indicates an instance_method, and the name is taint. However, with the current UnboundMethod API, we can only tell the owner and the name.
It would be very useful to also see the receiver type and whether the method is an instance_method without performing Regex on the output of to_s
.
In particular, UnboundMethod#receiver
would be useful, even though UnboundMethod does not logically have a receiver, because it would make it easier to tell what type of objects can be passed to UnboundMethod#bind
without raising a TypeError.
Updated by myronmarston (Myron Marston) over 9 years ago
I think that Method#instance_method?
and UnboundMethod#instance_method?
would be very confusing, because my mental model is that every method is an instance method of some class -- it's just that the class might be a singleton class. After all, if you do ENV.singleton_class.instance_method(:fetch)
it returns an UnboundMethod
object for the fetch
method that's defined as a singleton method on ENV
.
I think it would make more sense to add a #singleton_method?
predicate. While every method is an instance method of some class, only some methods are singleton methods.
Updated by matsuda (Akira Matsuda) over 9 years ago
- Assignee deleted (
tenderlovemaking (Aaron Patterson))
Updated by Eregon (Benoit Daloze) over 9 years ago
#receiver is not ideal since it has a different meaning for Method ("receiver type" is more what we want).
In JRuby it is called "origin" ("orig" in MRI) and the documentation of UnboundMethod says:
Unbound methods can only be called after they are bound to an
object. That object must be a kind_of? the method's original class.
So I propose #origin, which goes well along #owner.
As for the instance/singleton method, maybe it would make sense to expose Class#singleton?.
But I am unsure of what would be a valid use case for such a predicate. Why do you want to know if it is a "class method" or not?
Updated by nobu (Nobuyoshi Nakada) over 9 years ago
- Status changed from Open to Feedback
Benoit Daloze wrote:
So I propose #origin, which goes well along #owner.
How does it differ than #owner
?
A Method
is a method, the difference from UnboundMethod
is just if it has a receiver.
If respond_to?(:receiver)
returns true
, it's a callable (and bound) Method.
If a new method is really needed, callable?
or bound?
probably.
Updated by Eregon (Benoit Daloze) over 9 years ago
Nobuyoshi Nakada wrote:
Benoit Daloze wrote:
So I propose #origin, which goes well along #owner.
How does it differ than
#owner
?
It would return String in the example above.
A
Method
is a method, the difference fromUnboundMethod
is just if it has a receiver.
Ifrespond_to?(:receiver)
returnstrue
, it's a callable (and bound) Method.If a new method is really needed,
callable?
orbound?
probably.
I was just commenting on the naming.
Having the ability to check if a UnboundMethod can be bound to a given receiver seems useful though and #owner does not allow this.
Updated by Eregon (Benoit Daloze) over 9 years ago
Myron Marston wrote:
I think it would make more sense to add a
#singleton_method?
predicate. While every method is an instance method of some class, only some methods are singleton methods.
unbound_method.owner.singleton_class? seems enough then.
Updated by nobu (Nobuyoshi Nakada) over 9 years ago
Benoit Daloze wrote:
So I propose #origin, which goes well along #owner.
How does it differ than
#owner
?It would return String in the example above.
In the trunk, it is useless to tell if the method can be bound to an object.
$ ruby -v -e 'm = String.instance_method(:taint); p m.owner, m.bind(Object.new).call'
ruby 2.3.0dev (2015-08-30 trunk 51727) [universal.x86_64-darwin14]
Kernel
#<Object:0x007fa3dc8246c8>
Having the ability to check if a UnboundMethod can be bound to a given receiver seems useful though and #owner does not allow this.
You can do it by method.owner === object
.
Updated by Eregon (Benoit Daloze) over 9 years ago
- Status changed from Feedback to Rejected
I see, I tried with 2.2.2 which would not allow #bind in that case.
I'll close this then as both use cases have been addressed.
If there are other use cases for this feature, please open a new issue.