in reply to Re: Can @_ be extended?
in thread Can @_ be extended?

You can have your cake and eat it too :)

Use a prototype to avoid the backslash and assign the reference to a localised glob to avoid teh need to dereference in the sub.

#! perl -sw use strict; sub setmode ($\@) { ## the prototype makes the reference our @array; ## satisfy strict my $val = shift; local *array = shift; ## alias the reference splice @array, 1, 0, $val; ## do normal array operations } my @a = qw( one two three ); print join( "\n", @a ), "\n__________\n"; setmode 'add_test', @a; print join( "\n", @a ); __END__ [ 7:19:41.56] P:\test>junk3 one two three __________ one add_test two three

Whether the effort is worth may depend upon how much dereferencing you will do in the sub, and possibly whether the elements of the array might need further dereferencing.

Whether using prototypes, our and local is acceptable will depend upon your personal or corporate "acceptably unconfusing and mainatainable subset" of Perl's facilities and syntax.


Examine what is said, not who speaks.
Silence betokens consent.
Love the truth but pardon error.

Replies are listed 'Best First'.
Re^3: Can @_ be extended?
by hsmyers (Canon) on Feb 11, 2005 at 08:21 UTC
    A better grade of magic here. This is closer to what I was hoping for when I asked the question. Must be all that 'tolkien' in the air. My own preference would be for local and since I am both the 'personal' and the 'corporate' in this context it's a win no matter how I do it. Life is nice when you work for yourself---now if there were only money in it!??! Thanks BrowserUk

    Update:
    I note that this:

    sub setmode ($\@) { our (@array,$val); ($val,*array) = @_; splice (@array, 1, 0, $val); }
    works as well.

    --hsm

    "Never try to teach a pig to sing...it wastes your time and it annoys the pig."
      I note that this: ... works as well.

      Yep. Though I would write that as:

      sub setmode ($\@) { our( $val, @array ); local( $val,*array ) = @_; splice (@array, 1, 0, $val); }

      Ie. Order the values in the our to match the prototype, and localise the globals so that when you call this function from another that also uses one of the globals $val or @array, you don't stomp on their values by mistake.

      There are various aiasing packages on CPAN, but they mostly (all?) only allow you to alias similar types, which is different to aliasing a array name for an array ref as we are doing here.


      Examine what is said, not who speaks.
      Silence betokens consent.
      Love the truth but pardon error.
Re^3: Can @_ be extended?
by tphyahoo (Vicar) on Feb 11, 2005 at 13:23 UTC
    This won't work in perl 6, though, will it?

    In answer to my recent post Trying to understand aliasing (*var), dave_the_m wrote

    "Typeglobs, ie *foo are mostly an artifact of Perl 4, which didn't have references; they will be removed completely in Perl6"

    So that might be a reason to avoid this particular type of magic, and stick with a slash type \$reference.

      Typeglobs will go away in Perl6, but they will be replaced by a more consistent := aliasing operator. In Perl5 you would write *foo = \@bar in Perl6 you would write @foo := @bar.

      Though if I read Apocalypse 6 correctly then

      sub foo (@foo is rw) { ... } foo(@bar);
      Will alias @bar to @foo, in the same way as @foo := @bar does, for that call.

      I don't see a reason to avoid typeglobs if you must alias something in Perl5. Ponie (Perl5 running on Parrot) will certainly support typeglobs, and I don't a good reason to compleatly throw away a useful (but seldom to be used) technique just because the next major version of Perl will not use that syntax for aliases. Should I stop using objects in Perl5 because Perl6 has a totally different object syntax?

        Don't get me wrong - I completely agree that you can't throw something away just because it won't be in perl 6 (since pretty much the whole perl5 language would be thrown away). However, I think that tphyahoo's comment was more based on the "seldom used" part of your comment: there are some "more advanced" areas of perl 5 which, if you aren't already comfortable with them, may not be worth the effort to learn at this point. I'm not sure that typeglobs are in that category, but, as a generality, I think the logic makes sense. Where that line is drawn may be different for each person, but that the line exists for some people I think is a reasonable statement.

        Personally, I'm a complete geek, and won't stop abusing the crap out of perl 5 until perl 6 is somewhat established. But I can understand how that may not be true (or even should not be true) for some people.