Project

General

Profile

Actions

Feature #11491

closed

Add descriptive methods to Method & UnboundMethod

Added by searls (Justin Searls) about 9 years ago. Updated about 9 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:<unknown>]

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? and UnboundMethod#instance_method? to indicate whether the method is an instance or a class method
  • UnboundMethod#receiver to provide the type required to be passed to UnboundMethod#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.

Actions #1

Updated by myronmarston (Myron Marston) about 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.

Actions #2

Updated by matsuda (Akira Matsuda) about 9 years ago

  • Assignee deleted (tenderlovemaking (Aaron Patterson))
Actions #3

Updated by Eregon (Benoit Daloze) about 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?

Actions #4

Updated by nobu (Nobuyoshi Nakada) about 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.

Actions #5

Updated by Eregon (Benoit Daloze) about 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 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.

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.

Actions #6

Updated by Eregon (Benoit Daloze) about 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.

Actions #7

Updated by nobu (Nobuyoshi Nakada) about 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.

Actions #8

Updated by Eregon (Benoit Daloze) about 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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0