http://www.perlmonks.org?node_id=265354


in reply to Re: chaining method calls
in thread chaining method calls

This is an important point on idiom, and since idiom is a matter of choice of expression, I won't weigh one way or the other, but will caution that Perl's ruthless lack of discipline, while a benefit in many cases, complicates things for those who prefer or need consistent design.

In Perl, there's no difference between a "message" to an object and a "functor" answered by an object. Thus, obfuscation aside, they both have to use the same invocation syntax: $a->b().

The following distinction is my own OO philosophy, sometimes consistent and sometimes inconsistent with others I've seen, but I think it's a very useful paradigm.

Messages should be invoked for side-effects, and should have no immediate return value, so that (1) they can be transaction-wrapped, (2) they never block the invoker, and (3) on some application architectures they can be posted onto a queue instead of handled immediately. If you stick to the "messages have no immediate return value" philosophy, then supporting it with a Perl return $self idiom makes sense.

Functors should not have side-effects (other than local caching), and should have an immediate return value. Again, these benefits complement message handlers: (1) they can be seen as atomic, (2) thus they may need to block, and (3) in a remote architecture, a dumb stub can return cached values but can't actually decide anything behaviorwise.

(Some people may think "ack! invoke for side effects which may not be done immediately?" If you must wait for a message transaction to be realized or verified, you wait with a functor that can block appropriately. Otherwise, you trust it will get done.)

Unfortunately, you can't easily tell a Perl "functor" from a Perl "message handler." They're both just subs. They're both invoked with $a->b(). If nobody makes a mistake, messages can chain with $self, but yet functors can't. Tread carefully.

--
[ e d @ h a l l e y . c c ]