Ruby parens-free function calls [was Re: Accessing parent objects]

Steven D'Aprano steve+comp.lang.python at pearwood.info
Tue Mar 27 19:52:52 EDT 2018


On Tue, 27 Mar 2018 09:28:34 -0700, Rick Johnson wrote:
> On Tuesday, March 27, 2018 at 8:46:54 AM UTC-5, Chris Angelico wrote:
[...]
> > Cool, so Greg was right: you can't get a reference to a method or
> > function. You need magic to simulate it.
>
> Since when did utilizing a method to request a specific value become
> some sort of magic?

Since it requires a special method that has super powers no method you 
can write yourself can do.

Can you write a pure-Ruby method that does the same thing as 
Object.method, using only standard, public parts of the Ruby API? No 
special debugger hooks or "subject to change without warning" internal 
APIs or other private implementation details.

I don't believe you can.

If you can emulate Object.method, without calling Object.method either 
directly or indirectly, then it is not magic.

But if you can't, then it relies on private, esoteric knowledge of the 
Ruby internals not available to anyone else. In other words, magic.



[...]
> Even though i prefer Python's way better, the implicit return of Python
> function references is far more "magical" than making an explicit call
> to a method will ever be.

Let's say you have an object, lassie = Dog(). How do you get access to 
her tail? Do you use dot syntax:

    lassie.tail

or do you call some sort of special "attribute access method"?

    lassie.attribute("tail")


Of course you use the first. How is dot attribute syntax "implicit"? The 
dot for attribute access is right there, as is the name of the attribute.

None of this changes one iota if we write `lassie.bark` instead of 
`lassie.tail`. There's nothing "implicit" about it, it is as explicit as 
you can possibly get: use the dot attribute access (pseudo)operator to 
get a reference to the attribute, regardless of whether that attribute is 
a tail or a method.

The difference with Ruby is that they treat methods as a distinct kind of 
thing to other members, even though they use the same syntax (dot) for 
both. Yay for inconsistency!

Ruby attributes are always private. You must write accessor getter and 
setter methods if you want to access them from outside the instance or 
class. But once you have those accessors, you can use lassie.tail to 
access the member (attribute) tail, and lassie.bark to *call* the method. 
There is no member "bark" because methods aren't values.

That means to get access to a first-class value of the bark method, you 
need a special function, Object.method, which uses magic to wrap the 
method in an ordinary Ruby object. That's not needed in Python, because 
methods already are ordinary Python objects.



-- 
Steve




More information about the Python-list mailing list