Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Returning information from BEGIN

by leons (Pilgrim)
on Feb 21, 2001 at 19:34 UTC ( #59941=perlquestion: print w/ replies, xml ) Need Help??
leons has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I hope someone can help me with the following question. I have
the following construction in a program I am writing

#!/usr/bin/perl -w use strict; BEGIN{push @INC,"$ENV{'SM'}/../bin";}; require 'errors.pm';

Which ofcourse is quite tricky, because the $SM evironment-string
might be non-existent.
So ... being unfamiliar with 'BEGIN' I tried something similar to
the following:

#!/usr/bin/perl -w my $Err; BEGIN{$Err=1 unless $ENV{'SM'}; push @INC,"$ENV{'SM'}/../bin";}; die "Environment string: \$SM not set\n" if $Err; require 'errors.pm';

Which ofcourse was quite silly, because the BEGIN-block will be
run first. After that I tried a couple of other things, which
were, by the way, even more silly (other words come to mind ;-)
So here's the question ... (......) ... What variables (like
@INC are exported from the BEGIN-block to the main program,
in order to pass information to it, like in the example above

Your help is highly appreciated,

Thanks, Leon

Comment on Returning information from BEGIN
Select or Download Code
Re: Returning information from BEGIN
by arturo (Vicar) on Feb 21, 2001 at 19:58 UTC

    You can export a symbol from BEGIN by the old use vars qw($foo); trick:

    #!/usr/bin/perl -w BEGIN { use vars qw($foo); $foo = 'bar'; } use strict; print "$foo\n";

    Does that help? Are you just trying to suppress the "BEGIN failed" message that pops up if you put the die in the BEGIN block? The use vars will help with that:

    BEGIN { use vars qw($err); $err = $ENV{SM} ? 0 : 1; push @INC, "$ENV{SM}/../bin" unless $err; } die "Environment variable SM not set!\n" if $err; require 'error.pm';

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

      Thanks a lot arturo. And yep, that was exactly what I was
      trying to do ;-)

      Bye, Leon
Re: Returning information from BEGIN
by dash2 (Hermit) on Feb 21, 2001 at 20:06 UTC
    Not quite sure what the problem is - your BEGIN block gets run first, sets $Err if needed, then your program dies if $err is set. WFM.

    Anyway, AFAIK everything gets "exported" from a BEGIN block - except "my" variables, obviously. In that respect it is just like a normal block. It just runs earlier. "eval" is kind of the same, context remains, it just gets run later.

    Could you explain a bit more what you're trying to do?

    Dave

      Thanks! Yep, that was exactly what the problem was ... the "my"
      Which explains why this worked:

      BEGIN {$foo="hiya"}; print $foo."\n";

      Okay, feeling a bit silly, I thank you both and will continue
      writing this program after I drank a whole lotta coffee ;-)

      Bye, Leon

        Note that there is no problem with:

        my $Err; BEGIN { $Err= defined $ENV{SM} }

        Sure, the BEGIN happens at compile time but so does the declaration part of the my code. use strict didn't give you an error, did it? That is because $Err is getting declared at compile time before the BEGIN block is executed.

        What would be a "problem" is code like this:

        my $Err= 0; BEGIN { $Err= 1 if ! $ENV{SM} }
        because the my statement gets executed in two parts. The declaration part gets executed at compile time while the initialization part gets executed at run time. So the order or execution ends up looking more like this:
        my $Err; $Err= 1 if ! $ENV{SM}; $Err= 0;
        O-:

        Personally I prefer the my solution to using use vars inside the BEGIN block.

                - tye (but my friends call me "Tye")
Re: Returning information from BEGIN
by chipmunk (Parson) on Feb 21, 2001 at 20:52 UTC
    Your question about exporting variables from the BEGIN block does not make sense. BEGIN blocks are simply subroutines that are called at compile time. Other than that, they behave just like any other subroutine.

    Variables are exported from packages, not from subroutines.

      Okay, here is what I did:

      BEGIN { use vars qw($Bgn); $Bgn=1 unless $ENV{'SM'}; push @INC,$ENV{'SM'}||""."/../bin"; }; use strict; die "[Error] Environmental string not found: \$SM\n" if $Bgn; require 'errors.pm'; ... ...

      To avoid getting the ugly Error-message when die-ing in the
      BEGIN-block I wanted to set some variable which I would use
      after the BEGIN-block to check whether there was an error.
      In this case the error would have been the fact that the $SM
      environment string hadn't been set. Which would result in
      an error message in the BEGIN-block
      Use of uninitialized value in concatenation (.) at ./test.s line 19
      (Which was solved by the '||""'). And which would result in
      an error message due to the require 'errors.pm';
      Which could not be found in $SM/../bin/, because $SM hadn't
      been set.

      But fortunately, things are working now ;-)

      Thanks and Bye, Leon
Re: Returning information from BEGIN
by princepawn (Parson) on Feb 22, 2001 at 01:27 UTC
    In your case, you can simply
    use lib "$ENV{SM}/../bin";
    Since, per perlmod, use lib MODULE qw( ) is the same as
    BEGIN { require MODULE; import ( ) }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://59941]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (6)
As of 2014-08-23 02:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (171 votes), past polls