in reply to References

Personally I would suggest learning to live with the syntax rather than fighting it. But there are 2 solutions:
# Abuse the symbol table. This does not work under strict. sub a1 { local *c = shift; $c{a} = 'a'; } # Copy the hash by force. Very inefficient. sub a2 { my $ref = shift; my %c = %$ref; $c{a} = 'a'; %$ref = %c; }
However personally I would use the following solution instead as the best mix of safe, efficient, and readable programming with references:
# "Arrow" notation. sub a3 { my $ref = shift; $ref->{a} = 'a'; } # Or compactly sub a4 { (shift)->{a} = 'a'; }
TIMTOWTDI.

Replies are listed 'Best First'.
Re: Re (tilly) 1: References
by Cine (Friar) on Aug 19, 2001 at 21:18 UTC
    sub a1 { local *c = shift; $c{a} = 'a'; }
    Is almost what I want, but it will not work under strict, as you point out.
    I have however come up with two sollutions based on the same idea...
    1
    sub f { use vars qw(%d); local *d = shift; $d{f}='f'; }
    However this will declare %d globally, which is not what I want. so:
    2
    sub f { our %d; local *d = shift; $d{f}='f'; }
    But since I dont know how our works, I dont know how this works... Can someone explain?
      Our is a Perl 5.6 feature that gives lexically scoped access to a global variable. I dislike it for a number of reasons that are neither here nor there, but it should work from Perl 5.6.0 onwards.

      However for several reasons, not the least of which is that some day someone else will have to figure out your code and you will need to understand yet another person's, I strongly recommend getting used to the arrow syntax for dereferencing rather than playing games with the symbol table.

        I did some benchmarking
        #/usr/bin/perl -w use strict; use Benchmark; sub f { our %d; local *d = shift; $d{$_}=$_ foreach (0 .. 200); } sub b { my $d = shift; $$d{$_}=$_ foreach (0 .. 200); } my %c; timethese (100000, { 'f' => '&f(\%c)', 'b' => '&b(\%c)', });
        Which gives me:
        Benchmark: timing 100000 iterations of b, f... b: 83 wallclock secs (67.82 usr + 14.38 sys = 82.20 CPU) @ 12 +16.55/s (n=100000) f: 80 wallclock secs (65.86 usr + 13.95 sys = 79.81 CPU) @ 12 +52.98/s (n=100000)
        I was expecting there to be at least some difference, since b has to dereference it every time.