Correct, I both (minor) confused #send with #__send__ and misremebered the mechanism of some deep metaprogramming hacks involving a a mostly blank proxy object and #method_missing as using metaclasses and #send/#__send__ hacking; where that came from I don’t know. Should have not mentioned overriding (as its a tangent, in any case, as well as vmbeung wrong) or the #send method and referred to the fundamental underlying message send operation.
In contrast x.method(:foo) does do that proxy construction that you describe… because Ruby does not have first-class functions.
Python docs, section 3.2, subsection "Callable types".
https://docs.python.org/3/reference/datamodel.html#the-stand...
x.foo returns an "instance method object", which is a "callable type". Also referred to as a "bound method", the same term that Ruby and JavaScript use.
> When an instance method object is called, the underlying function (__func__) is called, inserting the class instance (__self__) in front of the argument list. For instance, when C is a class which contains a definition for a function f(), and x is an instance of C, calling x.f(1) is equivalent to calling C.f(x, 1)... Note that the transformation from function object to instance method object happens each time the attribute is retrieved from the instance... It is also important to note that user-defined functions which are attributes of a class instance are not converted to bound methods; this only happens when the function is an attribute of the class.
This last part is why the following program has an error:
def foo(self):
print(self)
class Foo:
def __init__(self, fn):
self.foo = fn
x = Foo(foo)
x.foo()me:
> If it's a callable then it can be called with parens
The docs:
> These are the types to which the function call operation (see section Calls) can be applied:
True of Python instance method objects. False of Ruby Methods and Procs. Therefore Python has first-class methods, and Ruby does not have first-class functions nor first-class methods. End of discussion.
This isn't the case. If you override `send` it only affects direct usage of `send`. You can't override method dispatch. You can in some other OO languages but not Ruby.
Agreed otherwise. `x.foo` in Python and `x.method(:foo)` in Ruby do the exact same thing -- return a bound method object that can be called. These are both "proxies" in a sense but they're also first-class functions in all meaningful senses.