A colleague of mine came with a program looking more or less like this. What do you think is the output ?
use strict; use warnings; my $obj = Obj->new(11); print $obj->meth, "\n"; #----------- package Obj; #----------- use strict; use warnings; my $foo = 22; my $bar = 33; sub new { my ($class, $arg) = @_; my $self = bless {arg => $arg}, $class; } sub meth { my ($self) = @_; return "$self->{arg} / $foo / $bar"; }
It looks so obvious : the answer must be 11 / 22 / 33. But this is wrong! We get trapped by being so used to external packages, where everything is initialized at load time.
Here, everything is in the same file. So the main program starts, new and meth get called before $foo and $bar are initialized, and the result is 11 / / , with a warning about uninitialized values!
It means BEGIN { require Foo; Foo->import; }
.
Note the BEGIN
block!
If you’re going to inline a package into another file that would normally use
it, don’t forget to wrap the whole thing in BEGIN
.