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.
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.
Procs are functions (at least, they are functionally equivalent to Python functions—as pure OO languages, in both Ruby and Python first-class callable entities are richer than classic functions, even when counting closures as a kind functions and not a separate thing that includes a function, because they can carry metadata besides the environment of a closure.)
> It's in the Wikipedia page.
The Wikipedia page is wrong in that conclusion.
> The identifier of a regular "function" in Ruby (which is really a method) cannot be used as a value or passed
A method is a very different thing than a function. But, on a deeper level, I think it is also a mistake to call the thing it is referring the identifier for the method, its just syntax sugar for a symbol passed to a #send call, which, if send isn't overwritten on the sender (which it probably shouldn’t be, overriding send is a good way to cause chaos) will result in the method being called, unless some other method has priority.
> The syntax for calling such a function object differs from calling regular methods
The syntax is different only inna waybthat reflects thebdifferent behavior. Calling #call on a Proc or Method object (again, assuming a sane world where the object’s send method isn’t overidden) does dynamic method lookup on the :call name in the Method or Proc, and its syntax is exactly normal method-call syntax for that behavior (unless you use the shortcut syntax of “.()” for “.call()”, but that's just syntax sugar).
Using normal method call syntax does dynamic lookup on the method name provided in the call on the receiver object identified in the call.
That is, Ruby methods are first class, but what it is a convenient shortcut to think of as “method call syntax” in Ruby is not really method call syntax, it is syntax for a message send that will (by overridable default) result in calling a method with that name if it exists in the ancestor chain of classes for the object, so it is inaccurate to view the “method call” syntax excluding any parameters as “the identifier for the method”.