in reply to Importing variables from package within same script

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.

Replies are listed 'Best First'.
Re^2: Importing variables from package within same script
by moensch (Novice) on Jan 15, 2010 at 15:17 UTC

    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";