http://www.perlmonks.org?node_id=189512

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

Hi Monks

I have a custom package - let's call it Custom::Package :) - which I want to include in all my CGI scripts. It's basically just a collection of useful functions and routines, including some stuff I have to configure to use a database.

Anyway, I want this package to do some "magic" for me as well - basically, hold the configuration for all the different environments my scripts run on. This includes setting up filepaths, DBI environment, etc., but I'd also like it to magically do things on the development server which get turned off in production.

Specifically, is there any way I can use the module to turn strictures on and off dependent on location? I can import certain modules based on location (I rolled my own importer which automatically places the modules in main::), I can turn warnings on and off ($^W is pretty global), but I can't find a way to turn 'strict' on from within a package.

Does anyone have any ideas? Is there something I've missed?

  • Comment on Triggering 'strict' from within a package

Replies are listed 'Best First'.
(tye)Re: Triggering 'strict' from within a package
by tye (Sage) on Aug 12, 2002 at 15:53 UTC
Re: Triggering 'strict' from within a package
by Abigail-II (Bishop) on Aug 12, 2002 at 15:46 UTC
    strict.pm is one of the simplest modules in the Perl distribution. Just copy the functionality in your custom package.
    package Custom::Package; sub import { $^H |= 0x604 unless $ENV {ENV} eq "PR"; } sub unimport { $^H &= ~ 0x604 unless $ENV {ENV} eq "PR"; } 1;
    Assuming you use the ENV environment variable to flag a production environment.

    Don't believe those who claim it cannot be done - this is only one of the ways how to do it.

    But I'd like to know why you want to turn off strictness in production code.

    Abigail

      Hmm, $^H, that's the one with "don't cross the streams" written all over it, isn't it? :) I think I prefer tye's solution, although you've given me another lesson (always check the module). I had mistakenly assumed there wouldn't be a strict.pm, since it was just a pragma, although I was slightly confused in Exporter.pm when I saw there was no code to handle the pragmas differently.

      As for turning off strict, it's mainly about keeping the webserver log files clean - we do a lot of traffic analysis on the log files (even the error logs), and Perl error messages can sometimes screw it up. Plus, we have an alternative system for collecting error messages and assertion failures. It's not as tight as strict, but that's the opportunity cost.

      Thanks!

        But Perl doesn't know pragmas. It's not a thingy in the language itself. It's just there for humans. The language really doesn't care whether you use a capital letter in the first argument to a use statement or not.

        As for tye's solution, that's neat, although I think I prefer to use goto &strict::import - just in case a future version would start using caller.

        Abigail

        I still don't understand. Is there any case where strict merely produces a warning?

        I was under the impression that strict's only effect was to cause the compilation phase to fail if it didn't like the code. Are you sure you are not confusing strict with warnings? Or did I miss something?

        > it's mainly about keeping the webserver log files clean

        But if you get your script working on the stage server, before moving it to the production server your 'use strict' shouldn't add anything to your webserver logs. Unless I'm mistaken, which did happen once before.

Re: Triggering 'strict' from within a package
by runrig (Abbot) on Aug 12, 2002 at 16:47 UTC
    After reading Abigail-II's answer and tye's answer, I looked in perlvar for $^H and found something almost identical to tye's answer:
    BEGIN { require strict; strict->import('vars') if $condition } # which to import all restrictions would be BEGIN { require strict; strict->import if $condition }
Re: Triggering 'strict' from within a package
by Joost (Canon) on Aug 12, 2002 at 14:59 UTC
    I rolled my own importer which automatically places the modules in main::

    Ah, you mean the package main; importer code :-)

    Anyway, strict is a lexical pragma, so you cannot set at it for other files. I assume this was done to keep non-strict code working together with strict code.

    this is also one of the reasons you have to use strict; for every module you use instead of defining it in the top-level code.

    Update: I cannot think of any reason to turn off strict based on the location of the script, so I would suggest keeping it on where it makes sense.

    Hope this explains a bit,
    Joost.

    -- Joost downtime n. The period during which a system is error-free and immune from user input.
      Ah, you mean the package main; importer code :-)

      Sadly not :) It will actually look at other stuff - such as @INC ordering - based on location (& other factors) also, so it will actually load different version of a module based on what environment the script is being run in.

      Anyway, strict is a lexical pragma, so you cannot set at it for other files. I assume this was done to keep non-strict code working together with strict code

      I had a horrible feeling something like that might be the case. Note, though, that it's not a case of turning it off, but more a case of not turning it on - it's just not useful in a lot of cases.

      Cheers!

        Note, though, that it's not a case of turning it off, but more a case of not turning it on - it's just not useful in a lot of cases.
        Describe "a lot of cases" where "it's just not useful". Either you're badly informed, or I am.

        (I can see the gallery taking side bets. {grin})

        -- Randal L. Schwartz, Perl hacker

Re: Triggering 'strict' from within a package
by erikharrison (Deacon) on Aug 12, 2002 at 18:54 UTC

    Perhaps I am a bit late in the game here to answer your question, especially after such astute answers from tye and Abigail-II. However, with any case of trying to make "meta" declarations from outside the lexical space I would use a source filter to tack the appropriate boilerplate code to the begining of the file prior to it being parsed.

    Cheers,
    Erik

    Light a man a fire, he's warm for a day. Catch a man on fire, and he's warm for the rest of his life. - Terry Pratchet