Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Importing variables from package within same script

by moensch (Novice)
on Jan 14, 2010 at 17:02 UTC ( [id://817438]=perlquestion: print w/replies, xml ) Need Help??

moensch has asked for the wisdom of the Perl Monks concerning the following question:

Hi all I am trying to import a variable into the main name space from a package which is defined within the same script. Having my separate package in its own file an using use (or BEGIN { require; import; }) does the right thing. So I am wondering, why does the below not work?
#!/usr/bin/perl -w { package jim; require Exporter; our @ISA = qw(Exporter); our $bar = 'foo'; our @EXPORT_OK = qw($bar); } package main; use strict; import jim qw/$bar/; print "our bar $::bar\n"; print "pkg ".__PACKAGE__." - bar: $bar\n";

Replies are listed 'Best First'.
Re: Importing variables from package within same script
by chromatic (Archbishop) on Jan 14, 2010 at 21:11 UTC

    Short answer: the strict variable declaration check occurs before the import.

    Long answer: the entire program compiles, then it runs. require is a runtime operation here. So is the import() call. When those happen together, as in the case of use, the implicit BEGIN block forces those operations to occur during compilation. Any code after that (in terms of line number in the file) is subject to any changes as a result of any import() operations.

    Perl always performs the strict variable checking during compilation time; that's the earliest it can possibly do so. There's no (good) way Perl can know that you intend to modify the compilation environment at runtime, so it won't delay the variable checking. Nor would you want it to in general; that'd lead to unpredictable behavior.

    The best solution is to put jim in its own package. You can work around the problem by wrapping that package and the import() call in BEGIN blocks.

      Thank you very much. This is all working as it should now.

      May I be cheeky and further the question by explaining the actual problem I am (was) trying to solve with this?

      I have a program which uses XML::LibXML and some of its constants (e.g. XML_ELEMENT_NODE). I want to modify the program to make it work on systems which do not have XML::LibXML installed and just make the functionality which require this module unavailable. The problem I faced: Even though I could put the 'require & import XML::LibXML' statements into an eval block, the compiler still moaned about me using Barewords (the now non-available XML::LibXML::Common constants).

      I have solved this problem as follows now, but am wondering if there is a "cleaner" approach to this rather than just importing "fake" constants from another package with a zero value instead.

      #!/usr/bin/perl -w BEGIN { package LibXMLVars; require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw(XML_ELEMENT_NODE XML_ATTRIBUTE_NODE XML_TE +XT_NODE XML_CDATA_SECTION_NODE); use constant XML_ELEMENT_NODE => 0; use constant XML_ATTRIBUTE_NODE => 0; use constant XML_TEXT_NODE => 0; use constant XML_CDATA_SECTION_NODE => 0; } package main; use strict; BEGIN { eval { require XML::LibXML; import XML::LibXML; require XML::LibXML::Common; import XML::LibXML::Common qw(:libxml); }; if ($@) { warn "Failed to import XML::LibXML"; import LibXMLVars qw(XML_ELEMENT_NODE XML_ATTRIBUTE_NO +DE XML_TEXT_NODE XML_CDATA_SECTION_NODE); } } print "Test: '".XML_ELEMENT_NODE."'\n";
Re: Importing variables from package within same script
by moensch (Novice) on Jan 15, 2010 at 15:11 UTC
    Truly awesome. Thank you! For those interested, this is what my (working) code now looks like:
    #!/usr/bin/perl -w BEGIN { package jim; require Exporter; our @ISA = qw(Exporter); our $bar = 'foo'; our @EXPORT_OK = qw($bar); } package main; use strict; BEGIN { import jim qw/$bar/; } print "our bar $::bar\n"; print "pkg ".__PACKAGE__." - bar: $bar\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://817438]
Approved by marto
Front-paged by MidLifeXis
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-23 15:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found