in reply to Re: Re: Perl Turning a Blind Eye
in thread Perl Turning a Blind Eye

I think your pseudo-defined complaint is more a matter of your having poor expectations, rather than Perl doing something unreasonable. What would your expectation be of this code?
my $foo; print_foo(); $foo = "Hello\n"; print_foo(); sub print_foo {print $foo;}
The first call shouldn't see the initialization because the straight-line code has a function call before my has been defined, and one after. Now should it matter where my is? How about these?
my %data = default_data(); sub whatever { my $self = shift; # ... }
When Perl first sees those it may not be able to even attempt to do the assignment.

Perl uses a very simple rule. There is stuff that it takes care of when it parses and compiles the file, and there is stuff that it takes care of when it executes. Figuring out what function to call and what variable is which is part of parsing and compiling. Actually doing things with those variables (like assignment and function calls) are taken care of at executation, which means that they have available to them other things that have happened already while executing, and the definitions of everything in your code.

What it also means is that function calls don't see assigments that haven't happened already. In other words Perl does actions in the order it sees them. Not very surprising at all when you think about it like that!

Now for your problem there are two obvious solutions. One is to move the functions and private data into its own module. Now you load and initialize that data in one obvious step. The other is to memoize your data lazily like this:

{ my %private_stuff; sub some_func { unless (%private_stuff) { %private_stuff = qw(some defaults); } # ... } }
This is something that tye and I have disagreed on for a bit. Personally I never use BEGIN in the way that he does, and I have yet to find a situation where I didn't find the above two solutions sufficient.