Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'd like to get some opinions from you guys about this piece of code I found:

sub to_xml { return shift->to_html(@_); }

It's short, elegant, and gets the job done. But is this something I should try to avoid emulating in my own code? Will it confuse people, and is it just bad practice in general to rely on the order of evaluations?

Thanks.

Replies are listed 'Best First'.
Re: One line accessor method style.
by Tanktalus (Canon) on Feb 23, 2005 at 18:02 UTC

    I do it all the time. No big deal. Of course, this being perl, there are a few more ways to do it...

    # implicit return. sub to_xml { shift->to_html(@_) } # get rid of shifting - only if there is no one deriving off # this object, and to_html is in the same package. sub to_xml { to_html(@_) } # what are we passing in @_ for? sub to_xml { &to_html } # ah, heck, this whole thing is just an alias anyway. *to_xml = \&to_html;

    Note how once we get rid of the shift, anyone who overrides to_html won't see their overridden version when the call is to_xml. So the behaviour is a little different in that case. I don't think any other use of to_xml would be different between all these ways.

    Update: If the overriding difference doesn't bother you, I do think the last one is the fastest as it avoids an extra subroutine call. It's also something that many people don't see too often, so you may avoid it for that reason, too.

      Thanks.

      What I was really more curious about is how idiomatic the construct is. I think it's perfect for simple delegation, like this:

      sub find_text { return shift->text_control->search_for(@_) }

      where you have one object containing another and you wish to delegate certain responsibilities to the contained object.

        Idiomatic? I think pretty much all of the above are idiomatic to some degree. However, the simple case in the OP is idiomatic to any API, whether Perl, C, Java, or other. The concept is simple: we're renaming a function, but we don't want to break old code, so we'll provide a forwarding function which will call the new function automatically. In Java, this is often combined with some Javadoc that says it's @deprecated - code that is already compiled against the deprecated function will continue to work, new code trying to be compiled against it will get a warning during compilation.

        The exact syntax to get this behaviour is quite idiomatic to Perl, but what it's trying to do is common across many languages.

        As to your new example, that, too, is idiomatic to OO languages. The precise syntax, of course, is again Perlish. But the concept (the idiom) is common to OO languages everywhere - one object "HASA" second object. When I myfoot->press( mycar->get_accelerator() ) ... then a series of actions happen:

        sub Foot::press { shift; shift->press(@_); } sub Accelerator::press { my $self = shift; my $fuel_amount = $self->convert_pressure_to_liters(@_); $self->get_car()->get_engineblock()->burn_more_fuel($fuel_amount); }
        This may be written in perlish pseudo-code, but it applies the same to any other language.

Re: One line accessor method style.
by friedo (Prior) on Feb 23, 2005 at 16:50 UTC
    It's a somewhat common style of accessor, and I think it's fine. If you're really worried, include a comment above explaining how they work. You can even get rid of the return if you want, too. (But personally, I hate implicit returns, even for one-line functions.)
Re: One line accessor method style.
by Anonymous Monk on Feb 23, 2005 at 17:39 UTC
    It's short, elegant, and gets the job done.
    Sounds like typical Perl to me.
    Will it confuse people
    No doubt it will confuse people. It's almost impossible to write some code that doesn't confuse people. And there will always be people (and unfortunally, relatively more of them can be found on perlmonks) who try to enforce some arbitrary rules on how people should code because it otherwise confuses them (although they try to claim it confuses everyone else as well). Example where this happens:
    • bless {...}, ref($_[0]) || $_[0]
    • map in void context
    • using a double quoted string without interpolating something
    is it just bad practice in general to rely on the order of evaluations?
    Not at all. It's only bad practice to rely on the order of evaluation if the order isn't defined. But the order is defined in your case. From perlop:
    Operator associativity defines what happens if a sequence of the same operators is used one after another: whether the evaluator will evalu- ate the left operations first or the right. For example, in "8 - 4 - 2", subtraction is left associative so Perl evaluates the expression left to right. "8 - 4" is evaluated first making the expression "4 - 2 == 2" and not "8 - 2 == 6".
    And then, skipping a paragraph, it defines -> to be left associative.
      Urgh. Each one of those items have very good, if complex, reasons why they should be avoided. And, there are performance reasons, as well. Particularly with map in void context in Perl before 5.8.

      If you have a beef with someone in particular (merlyn, maybe?), have the courage of your convictions to stand up and make your thoughts attributable. Every single person in the top 100 Saints has disagreed with every other member of the top 100 Saints on numerous occasions. Yet, we all still seem to get along just fine ...

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      Thanks for your reply.

      I disagree with you on all three of your examples, though. The first looks plain ugly, not elegant, and the second seems tailor-made for "for" or "foreach". The third seems like splitting hairs, but unless the string has interpolation or \' characters in it, why would you want to expend the additional effort to press the shift key?