sherr has asked for the wisdom of the Perl Monks concerning the following question:
I hope someone can enlighten me about a small problem I have.
I am writing a set of modules and want to use a global application configuration hash. Because some config depends on the system I run on, I thought I would use a BEGIN block to assign a config hash key based on the hostname. The BEGIN makes sure that this host dependent setup happens first.
However, in testing, I am seeing behaviour I am having trouble understanding.
If I assign a key inside the BEGIN to this global hash, I don't see it in the test program, unless no other keys are set in this global config hash.
Can someone explain this or direct me a decent explanation? I have looked at perlmod but still have trouble. This is Perl v5.10.0 on Debian Lenny.
Test program ttt.pl :
#!/usr/bin/perl -w use Test::More tests => 1; use ttt qw(get_key); my ($a,$b,$c) = get_key(); is($a,1);
This gives a test FAILURE - we get "undef" for $a, not 1 :
package ttt; use strict; use warnings; our @ISA = qw(Exporter); our @EXPORT = (); our @EXPORT_OK = qw(%config get_key); our %config = ( 'key' => [undef,undef,undef], ); BEGIN { $config{'key'} = [1,2,3]; } sub get_key { return @{$config{'key'}}; } 1;
If I replace the %config hash initialisation with just a declaration, it works. This passes ($a is 1):
package ttt; use strict; use warnings; our @ISA = qw(Exporter); our @EXPORT = (); our @EXPORT_OK = qw(%config get_key); our %config; BEGIN { $config{'key'} = [1,2,3]; } sub get_key { return @{$config{'key'}}; } 1;
Trying to understand this failure, I thought it was because the %config assignment (to "undef") happens AFTER the "BEGIN" assigns (1,2,3) - so the key value is over-written with "undef".
However ...
If I assign ANY key/value in the declaration of %config, I get an error e.g.
This also fails :
package ttt; use strict; use warnings; our @ISA = qw(Exporter); our @EXPORT = (); our @EXPORT_OK = qw(%config get_key); our %config = ( 'a' => 'test', ); BEGIN { $config{'key'} = [1,2,3]; } sub get_key { return @{$config{'key'}}; } 1;
I get :
Can't use an undefined value as an ARRAY reference at ttt.pm line 21. # Looks like your test died before it could output anything.
Every/Any config assignment has to happen inside the BEGIN. And I need to do it BEFORE the 'key' assignment i.e.
our %config; BEGIN { %config = ( 'a' => 'test' ); $config{'key'} = [1,2,3]; }
is OK
our %config; BEGIN { $config{'key'} = [1,2,3]; %config = ( 'a' => 'test' ); }
Gives an error :
Can't use an undefined value as an ARRAY reference at ttt.pm line 21.
What is happening here? Many thanks.
Alastair Sherringham
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Problem using BEGIN in module and retrieving global data from hash
by Anonymous Monk on Nov 21, 2010 at 15:15 UTC | |
by sherr (Novice) on Nov 21, 2010 at 15:24 UTC |