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

I found a neat little trick in Effective Perl Programming, but it doesn't pass 'strict refs'. And this doesn't make me happy. How do I go about fixing it so that it does work? And is this an alias or a typeglob? And do I have to use local instead of my in the subroutine? Here's my simple script.
my(@array) = qw(one two three four five); duhbub(\@array); sub duhbub { local(*aref) = shift; print("$aref[1]\n"); }
without 'use strict', it works. with 'use strict', i get the following error messages:
Variable "@aref" is not imported at ./reftest.pl line 8.
Global symbol "@aref" requires explicit package name at ./reftest.pl line 8.
Execution of ./reftest.pl aborted due to compilation errors.

Replies are listed 'Best First'.
Re: Reference optimization (alias/glob)
by Ovid (Cardinal) on Nov 15, 2002 at 19:53 UTC

    That's because local only works on package variables, not dynamic ones. Since you don't have a package variable named @aref, you get an error. You can do a couple of things. Either declare the package variable with use vars or our, or explicitly use it as a package variable (and lose the benefits of strict).

    use strict; my(@array) = qw(one two three four five); duhbub(\@array); sub duhbub { local(*aref) = shift; print("$::aref[1]\n"); }

    I wouldn't do this, though. The local *aref trick was primarily for Perl 4 programmers as a hack to get around lack of references by using typeglobs rather than the entire data structure. You could then use typeglobs inside of your data structure to simulate complex data structures. Now we have references so there's no need for the hack.

    Cheers,
    Ovid

    New address of my CGI Course.
    Silence is Evil

Re: Reference optimization (alias/glob)
by RMGir (Prior) on Nov 15, 2002 at 19:50 UTC
    You need to fully-qualify your aref to make this strict-compliant.
    my(@array) = qw(one two three four five); duhbub(\@array); sub duhbub { local(*MAIN::aref) = shift; print("$MAIN::aref[1]\n"); }
    Voila! Instant -w/strict happiness :)
    --
    Mike

      Shouldn't that be $main::aref rather than $MAIN::aref?


      Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
      Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
      Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
      Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

        Good question.

        MAIN::, main::, and just :: all work.

        HAH! Even funnier, RMGIR:: also works. I think the local auto-vivifies the namespace :)
        --
        Mike

      now you've got me concerned about namespaces, and all the extra typing. would the optimization be that great to deal with those issues?

      for namespaces, i would then have to use package names and main, and ensure that nothing's clobbering anything else. whereas normally within a block/subrouting using my is good enough.

      for the extra typing, it would just get annoying.

Re: Reference optimization (alias/glob)
by BrowserUk (Patriarch) on Nov 15, 2002 at 20:16 UTC

    In addition to the above, as the main utility of aliasing a reference in that way is to simplify the syntax of using the ref, having to type the extra $main::aref[1] or $::aref[1] isn't that much better that typing $aref->[1]

    However, you can avoid even this inconvenience by using the vars pragma. eg. use vars '*aref';

    Once you have informed the compiler that you intend to use a package global in this way, you no longer need to fully specify the prefix:

    #! perl -sw use strict; use vars '*aref'; sub test{ local(*aref) = shift; print "$aref[$_]\n" for 0..@aref; } my(@array) = qw(one two three four five); test(\@array); __END__ C:\test>213248 one two three four five

    Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
    Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
    Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
    Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

Re: Reference optimization (alias/glob)
by rir (Vicar) on Nov 15, 2002 at 19:59 UTC
    Stricture requires you to qualify or declare all your variables.

    Use  use vars qw/ *aref/;