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

Re: Importing constans and variables when "require"ing

by Paladin (Vicar)
on Feb 22, 2019 at 21:57 UTC ( #1230429=note: print w/replies, xml ) Need Help??

in reply to Importing constans and variables when "require"ing

require is evaluated at run time. use is evaluated at compile time. Your errors are coming at compile time, and since the require hasn't been evaluated yet, the compiler can't know about what's in the file at that time. Change your require to use, and you should be good.

Replies are listed 'Best First'.
Re^2: Importing constans and variables when "require"ing
by bliako (Monsignor) on Feb 22, 2019 at 22:49 UTC

    Fair enough, but why does it work and print the value of $PI if I comment out the use of CONST in main entirely (i.e. main's last line)? Also adding a sub in XYZ and calling it from main works ok. Is it because it can live without unresolved subs until it actually has to call them? But it has to resolve each and every variable before execution (when using strict at least)?

    The long story is that I ended using require because I have a module which overrides a core sub (sleep) via a BEGIN block. I need that to apply for ALL subsequent modules, mine or foreign, and I kind of reasoned that loading everything else at runtime (via require) will make sure that this is satisfied and sleep is overriden. Now I am not sure whether a module used via another module is using the overriden sleep version.

      > Fair enough, but why does it work and print the value of $PI if I comment out the use of CONST in main entirely (i.e. main's last line)?

      Strict has 3 effects, one (subs) is to restrict the use of barewords to only known subs. Constants are implemented as subs and need to be known at compile time.

      See also "use subs "

      This doesn't necessarily mean that the sub known at compile time is also the called sub, because resolution happens at run time. (Keep in mind that you can redefine subs dynamically, this will just update the reference in the symbol table)

      Any sub called with & or trailing () is not a bareword anymore, and not effected by strict.

      Another effect of strict (vars) is to enforce pre declaration of unqualified variables with my or our.

      But your variables are fully qualified. And barewords are not variables (under strict).


      It all becomes much easier if you first understand how Perl works without strict, an why these restrictions need to be done.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        Thanks for the added clarifications. Being quite lazy I never searched into the manuals for what a Perl constant is. I just assumed it would be the same as C. And that's why I use it often: more for (thinking) being lighter than a variable and much less for its read-only property. I did see smoke signals in forums saying that they never really use Perl constants, there is no point, but I ignored them. And so a constant is a sub with constant return value which ideally would be optimised by Perl to become more-or-less C #define.

        That also explains the fact that there is no complain if I replace what Perl sees as a bareword "XYZ::CONST" with its sub equivalent "XYZ::CONST()" something like what Perlbotics suggested but without the use const.

        So a Perl constant is a glorious sub and would be lighter than a variable if Perl eventually optimises it to a constant realising that it has a constant return value. And it's read-only. Great!

        Now, why does it complain with Name "XYZ::PI" used only once: possible typo when I print the foreign variable (print $XYZ::PI). Doesn't the definition of "use" include write AS WELL as READ?

        bw, bliako

        You are right, that previous post has many gem answers. I am just not absolutely sure that they can work in ALL situations where modules load other modules etc. My conclusion was

        you must override/alias your sleep() BEFORE use statements for any modules which will use it
        and right now /with this post I am trying to make sure that the "BEFORE" is ensured 100%.

        The most bullet-proof way I guessed it was to override at compile time and then require all modules which happens at runtime, BEFORE is ensured 100%. However, that reveals side-effects. So I have to write tests for my specific case to ensure that BEFORE ... Thanks (and for your replies in the previous post).

        For the record that works and should work as long as it is use'd before any modules whose their sleep needs to be overriden (from LanX's answer at Copy a builtin sub to a different name and then override):

        package Override::Sleep; # based on LanX's answer at our $total_sleep_time = 0; our $DEBUG = 0; BEGIN { my $oldsleep = \&CORE::sleep; *CORE::GLOBAL::sleep = sub(;$) { #$Override::Sleep::total_sleep_time += CORE::sleep($_[0]); $Override::Sleep::total_sleep_time += $oldsleep->($_[0]); if( $Override::Sleep::DEBUG ){ my $parent = ( caller(1) )[3] || "N/A"; print 'CORE::GLOBAL::sleep('.$_[0].") (called by $parent): + total sleep time is now ".$Override::Sleep::total_sleep_time." secon +ds.\n"; } }; } 1;

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1230429]
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2023-12-02 18:32 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (18 votes). Check out past polls.