http://qs1969.pair.com?node_id=224284

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

Good Evening Monks,

I recently stumbled over a fact that didn't let me stop thinking about it.
I have two Perl scripts, let's say "index.pl" and "engine.pl".

Content of "index.pl":
#!/usr/bin/perl use strict require('engine.pl'); . . .
Content of "engine.pl":
#use strict; use CGI; use HTML::Template; use XML::Simple; . . . 1;
You see that the first line of the second script is actually a comment, because strict is already used in "index.pl".
I tested the use of strict twice. When I uncomment use strict; in "engine.pl", warnings and errors are printed out
(I intentionally did some bad things to test strict). Without use strict; in "engine.pl" the script does run without these warnings.
It seems to me that require() has turned off strict or has done something similar. Should I just go on double-using strict in both files?

Has anyone an idea of the circumstances given?

Thanks,
BioHazard
reading between the lines is my real pleasure.

Replies are listed 'Best First'.
(jeffa) Re: require() turns off strict?
by jeffa (Bishop) on Jan 04, 2003 at 18:47 UTC
    use strict only works in the current package ... for example:
    # file foo.pm package foo; $foo = 1; --------------------------- # file foo.pl use strict; use foo; print $foo::foo,$/; --------------------------- [jeffa@trinity perl]$ perl -c foo.pm foo.pm syntax OK [jeffa@trinity perl]$ perl -c foo.pl foo.pl syntax OK [jeffa@trinity perl]$ ./foo.pl 1
    UPDATE:
    s/package/scope/ -- thanks pg and hawtin :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      #define PEDANTIC_MODE 1

      use strict only works in the current package

      I think you meant to say "use strict only works in the current lexical scope" which is slightly different from the current package. It could be that the two files had stuff from the same package (eg the main one).

      Update: Sorry I see that you have corrected that while I wasn't paying attention

        #ifdef PEDANTIC_MODE # include <limits.h> # define PEDANTIC_MODE INT_MAX #endif
        I think you meant to say "use strict only works in the current lexical scope" which is slightly different from the current package
        Nope, the current package holds for the length of the current lexical scope[1], which is usually the file-level lexical scope. See the docs for more info.
        HTH

        _________
        broquaint

        [1] although the 5.005 docs say it is dynamically scoped but I'm pretty sure it's lexically scoped because it takes effect at compile-time which isn't orthogonal with dynamically scoping

      Hi ,

      The mod-perl , when the cgi or pl is under mod-perl ,then the use strict; is needed to avoid global variables and hence require "perl.pl" is recommended not to be really used ( the reason) .
Re: require() turns off strict?
by pg (Canon) on Jan 04, 2003 at 19:13 UTC
    You actually discovered the fact that, "use strict" has a per lexical body scope (and your package is just one type of lexical body). Try this piece of code:
    @a = (1,2); print join(",",@a); { use strict; @b = (1,2); print join(",",@b); }
    Perl would tell you that @b requires a package name, but it does not complain about @a, because "use strict" is only specified for that {} scope.

    This actually makes sense. For example, you get a package from another person, and he didn't "use strict" in his package. Now you use his package in your package, and you specify "use strict". If this "use strict" is not per lexical body scope, but affects the whole script(remember his package is inside your script scope now.), Perl will probably refuse to run your script, because of all those problems in his package caused by your "use strict".

    I remember we had a thread a while ago, about the fact that, "use encoding" has a per script scope, instead of a per lexical body scope. You may want to compare those two different types of scopes. I have a node on that topic.
      Hi there,

      Thanks for the great resonance. I might see a little bit logic in this case.
      Another point is that the second file was actually not a package but a simple .pl file in my example.
      But that doesn't seem to make a difference for strict.
      So I will try to include the strict pragma whenever a new logical or lexical body scope begins in order to guarantee "strict Perl programming".

      Greetings,
      BioHazard
      reading between the lines is my real pleasure
      For example, you get a package from another person, and he didn't "use strict" in his package. Now you use his package in your package, and you specify "use strict". If this "use strict" is not per lexical body scope, but affects the whole script(remember his package is inside your script scope now.), Perl will probably refuse to run your script, because of all those problems in his package caused by your "use strict".

      Like CGI.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Re: require() turns off strict?
by Anonymous Monk on Jan 05, 2003 at 07:34 UTC
    Given the above responces, I have a question:

    Lets say you have 10 .pm files your using in a program and one contains a list of global variables. As an example lets say one of them is $program_name = "foo"; and another is $version = "0.1";

    If i wanted to use these through all the modules, AND use strict. How would I go abut doing this?
      Export them using Exporter and "use" the module containing the globals in each module you need those variables in.
Re: require() turns off strict?
by Vuen (Initiate) on Jan 06, 2003 at 03:11 UTC
    Um, I'm confused. Does this apply to other calls to 'use'? I have a cgi script with 3 modules; I only 'use' the modules once in the perl script, and then the modules can all interact with eachother without having to 'use' eachother individually. Why doesn't this work with 'use strict'?
      As I understand it 'use' actually does two things, both of them conditionally:

      1. Perform a sort of compile-time 'require' *only if* this module hasn't been 'use'-d before. A table of what modules have already been loaded is maintained in some variable that I don't recall at the moment.

      2. Call the 'import'-function (I think) *if* it is present in the 'use'-d package. This is performed on every occurence of 'use'. The import function is the one that can optionally export symbol-names (like your constants) to the calling package.

      Building your own import function is a hassle, so the easy way is to use the standard Exporter package... The man-page of the Exporter package can explain everything you want to know (and a lot more) about exactly how to use it. For starters, this should do:

      --file foo.pm--

      package foo; use Exporter; @ISA=qw(Exporter); @EXPORT=qw($const1 $const2 $const3); # rest of package including constant data
      If you'd just require'd the foo package, you would need to use $foo::const1 to access the constant.

      If you'd use'd the foo package, the same would still work, but you would also have access using $const1 from the calling package.

      Hope it helps...

        A table of what modules have already been loaded is maintained in some variable that I don't recall at the moment.
        That would be the %INC hash.
        (I think) *if* it is present in the 'use'-d package.
        Not quite. If you specify an empty import list as in use Module (); then its import() won't be called at all (not even with no parameters).

        Makeshifts last the longest.