On the first morning of the 10th German Perl Workshop Max did a tutorial on Advanced Perl during which someone asked about the difference between our
and use vars
. Max didn't know the answer offhand (and being smart, doesn't need to pretend to be by pretending to know the answer), and I had to scratch my head a bit when Jürgen told me about it (I'd been in the other tutorial), so Jürgen asked if I could do a lightning talk to explain it. I said yes (which seemed to be consistent with a question at breakfast - Jonathan asked "are you speaking this year?" and I replied "not yet").
However, today it turned out that it is a good thing that I am a virtuously lazy programmer and hadn't written any slides, as Steffen Ullrich did an excellent talk on Perl Gotchas which had an example of code which explained it much better than I could. Specifically, consider the following:
!/usr/bin/perl -w
use strict;
package awk;
# ...
package urkk;
our @ISA = 'awk';
# ...
package rakkk;
our @ISA = 'urkk';
# ...
package owww;
@ISA = 'rakkk';
# ...
1;
All nicely strict
clean:
$ perl -Mawk -e0
but nevertheless buggy. Why? Because the inheritance isn't set up correctly:
$ perl -Mawk -wle 'print @owww::ISA'
$ perl -Mawk -le 'print @rakkk::ISA'
rakkk
$
Erk! How did that happen? It's because the our was missed from the last assignment. It should read:
package owww;
our @ISA = 'rakkk';
But without that our, that last assignment is still to the variable @rakkk::ISA
, not @owww::ISA
, because our
actually creates a lexical alias to the global variable, a lexical that is still in scope for the rest of the file.
Whoops! Gotcha!
$ perl -wle 'package foo; our $_; print map {$_} 1..5'
Use of uninitialized value in print at -e line 1.
Use of uninitialized value in print at -e line 1.
Use of uninitialized value in print at -e line 1.
Use of uninitialized value in print at -e line 1.
Use of uninitialized value in print at -e line 1.
Re:Sooo....
chromatic on 2008-02-15T01:19:04
File-scoped
our
variables could be a problem. Block-scopedour
variables are less troublesome.
Another small problem with our
variables is that they take twice the memory of lexical variables or plain global.
Re:Yet another gotcha
kwilliams on 2008-02-17T14:24:09
That comment is a bit misleading; if you have a 1000-byte string in anour
variable it's not suddenly going to consume 2000 bytes. It would be more accurate to say they take twice the overhead.