John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

If a method does a lot of work with member data, it seems inefficient to keep referring to $$self{x} over and over again. For many uses, it seems like it would be much more efficient to create a local lexical variable that's a reference to this value, e.g. my $x= \$${x}; and then refer to $$x in the function.

But for even heavier use, such as in a long loop, it would be even more efficient to copy the value to a local variable, and when done, copy the new value back.

But, I'm wondering if there is a nice way to simply make the local variable alias the other one without having to explicitly dereference it each time. For a single value, a dummy for loop that only executes one iteration can do exactly that. But is there a more general way?

—John

Replies are listed 'Best First'.
(tye)Re: Aliasing Variables
by tye (Sage) on Jul 22, 2001 at 10:51 UTC
    for( $self->{x} ) { # Do stuff to $_ }

    Yes, I'd love to see a way to say: my $x= aliasOf($self->{x}); Perl's internals are already up to the task, it just isn't supported in the syntax of the language. /: This may have to do with this being mostly useful as a speed thing and Perl not really being a "speed" kind of language?

    Update:

    for my $x ( $self->{x} ) { # Do stuff to $x }
    but that still isn't as general as it could be.

    Update2: ...but you already mentioned that.

            - tye (but my friends call me "Tye")
      my $x= aliasOf $self->{x} Maybe that should go on our wishlist for Perl 6. Or if it's an easy patch (hint hint!) or an XS that implements my $x; make_alias ($x, $self->{x}} would still help, though not as sugary of a syntax.

      —John

        package alias; use strict; BEGIN { use base qw(Exporter); @alias::EXPORT = qw(make_alias); } sub make_alias { tie $_[0], __PACKAGE__, \$_[1]; } sub TIESCALAR { my($class, $target_ref) = @_; bless $target_ref, $class; } sub STORE { my $self = shift; $$self = shift; } sub FETCH { my $self = shift; $$self; } 1;
        No XS here, works fine with 5.x, but maybe a little slow :)
        use alias; my $self = { x => 1 }; make_alias my $x, $self->{x}; $x = 100; print $self->{x}; # 100

        --
        Tatsuhiko Miyagawa
        miyagawa@cpan.org

(MeowChow) Re: Aliasing Variables
by MeowChow (Vicar) on Jul 22, 2001 at 11:51 UTC
    You may also want to take a look at Alias.
       MeowChow                                   
                   s aamecha.s a..a\u$&owag.print
      I found Alias, and it works by using blobs. It only creates package variables, not lexicals. That plays havoc with use strict.

      But it brings up another question. It implies that local can restore this binding. But Abigail's code on another thread implies that FETCH/STORE is used when localizing a tied variable, as opposed to just changing the binding. Does local work differently on tied variables, or is something else going on?

      —John

        Look carefully at the sequence and line numbers of the carp output from this:
          
        use strict; use vars qw($obj); use Carp qw(carp croak cluck confess); use Cwd; sub TIESCALAR { my $var; carp "tie:\t",\$var," = $_[0]\n"; bless \$var + => shift; } sub FETCH { carp "fetch:\t$_[0] == ${$_[0]}\n"; ${$_[0]} } sub STORE { carp "store:\t$_[0] = $_[1]\n"; ${$_[0]} = $_[1]} tie $obj => 'main'; $obj = 'foo'; { my $x = 1; my $y = $obj; local $obj = 'bar'; } ### OUTPUT ### tie: SCALAR(0x8106d78) = main main::TIESCALAR('main') called at - line 10 store: main=SCALAR(0x8106d78) = foo main::STORE('main=SCALAR(0x8106d78)', 'foo') called at - line +11 fetch: main=SCALAR(0x8106d78) == foo main::FETCH('main=SCALAR(0x8106d78)') called at - line 14 fetch: main=SCALAR(0x8106d78) == foo main::FETCH('main=SCALAR(0x8106d78)') called at - line 15 store: main=SCALAR(0x8106d78) = main::STORE('main=SCALAR(0x8106d78)', undef) called at - line +15 store: main=SCALAR(0x8106d78) = bar main::STORE('main=SCALAR(0x8106d78)', 'bar') called at - line +15 store: main=SCALAR(0x8106d78) = foo main::STORE('main=SCALAR(0x8106d78)', 'foo') called at - line +13
        I'm not sure exactly what you're asking, but I think this may answer your question :-)
           MeowChow                                   
                       s aamecha.s a..a\u$&owag.print
Re: Aliasing Variables
by petral (Curate) on Jul 22, 2001 at 05:04 UTC
    > perl -lwe'$x{y}=2; *z=\$x{y}; print$z; print$x{y}; $z=33; print%x' 2 2 y33 >
      p