in reply to Re (tilly) 1: References
in thread References

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?

Replies are listed 'Best First'.
Re (tilly) 3: References
by tilly (Archbishop) on Aug 19, 2001 at 21:44 UTC
    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.
        My guess is that any dereferencing overhead is invisible next to the overhead of constructing scalars and then stringifying them.

        As for the performance issue, the general programming principle is that premature optimization is the root of all evil. Furthermore if performance really is critical, then Perl is the wrong language to use. Perl will speed development, has very large reusable libraries, improves reliability by doing memory management for you, etc, etc, etc. But while it is fast for a scripting language, far faster ones exist out there.

        Cine - you're missing the point tilly's trying to make. The two syntaxes you're using, while legal, are horrid programming practice. Absolutely horrid.

        The first breaks all sorts of scoping suggestions by using a lexical global within a tiny function, then using a scoped global right after! Do not do this!! Whenever I see this kind of crap in some program I've been asked to maintain, I rip it out immediately. Of course, it usually takes me an hour or so to do this, just because I can never be sure that there aren't dependencies elsewhere.

        The second is a back-asswards way of dereferencing a hashref that would confuse the heck out of me, and anyone else who would read your code. I can read it now, but only because I have some context within which to read it. Again, if I ever saw this in some code I was maintaining, I would rip it out in a heartbeat!

        "What should I do?" you ask? Do the following:

        sub c { my $d = shift; $d->{$_} = $_ foreach (0 .. 200); }
        And get used to it! This is the way people will write code for you to maintain. You will read this syntax.

        In addition, if you're freaking out about which is faster, I decided to run your Benchmark script, adding in my subroutine. Just for kicks. Here're the results I got:

        b: 154 wallclock secs (153.27 usr + 0.00 sys = 153.27 CPU) @ 1216.55/s + (n=100000) c: 152 wallclock secs (153.17 usr + 0.00 sys = 153.17 CPU) @ 1216.55/s + (n=100000) f: 156 wallclock secs (156.57 usr + 0.00 sys = 156.57 CPU) @ 1252.98/s + (n=100000)
        Pretty interesting, huh?

        ------
        /me wants to be the brightest bulb in the chandelier!

        Vote paco for President!