in reply to Re: strict/do question
in thread strict/do question

Note that converting to "our" means that you're now using a global variable instead of a lexical variable.

Well, not quite.. our makes not global globals, but package globals (what if there's no package?). Also, it makes file globals whose scope spans packages in the same file. And our allows for sharing variables between files. But yes, our should be used with caution.

That said, I just don't like do FILE. do BLOCK is fine, but do FILE feels dangerous.

But require is IMHO just an enhanced do, and use an enhanced require. Aren't those functions nested like a Matryoshka doll? And innermost - there's just the eevil string eval: eval `cat $file`. I guess do, require and use are equally dangerous...

Please correct me if I'm wrong. (either me or perlfaq8 ;-)

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^3: strict/do question
by Tanktalus (Canon) on Nov 24, 2006 at 19:27 UTC

    If there is no package, it's ::, or main::. But that's the definition of "global" in Perl - a package variable is visible everywhere, even if you have to explicitly specify the package, while a lexical is not. It's similar to C++'s namespaces - sure, you can have more than one global variable, as long as they're in different namespaces / packages, but they're still global.

    The danger in do is just that Perl 5 has conventions. And those conventions are about useing modules, not evaling file contents. And because these are the conventions, that's what people are used to. When you buck those conventions, you introduce an error-prone area where nuances of the implementation (which are generously documented, but who looks at documentation? ;->) can bite you. For example, it seems common that people expect that do FILE will import lexicals (despite the docs). But I've not yet seen someone assume that from a use MODULENAME that has, as per convention, a package declaration at the top.

    That's not to say "never use do FILE" - just be sure you know what you're doing when you do so. It's an uncommon idiom, and, usually, a more common idiom would not only serve the same purpose, but be more maintainable. Even though I can't think of a good reason to use do FILE over either a proper module or a config file (depending on what the use is) doesn't mean I'm discounting the possibility. ;-)

      For example, it seems common that people expect that do FILE will import lexicals (despite the docs).

      Yeah, I see your (valid) point. And there's more to it:

      • require does set $@ if the file included is not found or if the last evaluated statement doesn't return a true value (even propagates it from inside an eval), while do does not.
      • do updates %INC regardless of compilation errors, while require does not.

      So yes, using do FILE without really knowing what it does can give unexpected results - but that's true for many more wonderful perl constructs, our not being the last... ;-)

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      Importing the symbols into :: or main:: is exactly what I want (there is no package). The script I'm aiming for has zero-configuration, i.e. all the stuff that can change is set in a cfg file that is held within a sandbox controlled under CVS, which I'm do'ing". Most of these variables need to be in global (or in package, if there was one) scope, as they need to be read by most of the subroutines in main. Ideally what I want is #include "import.pl" but for reasons in the article above this isn't really there, unless you do some funky odd looking stuff with the DB module. I'd rather avoid funky odd looking stuff for this software as lots of people need to use and understand it. I do find it odd that an old C-coder like Larry W would choose not to give people the ability to #include. Someone alluded to the idea that do'ing a file is kinda unsafe - presumably because you could be sucking up any old kind of stuff there which could break the main program? But I think I'm right in saying that unless the main program has use $variable then having the same in the file which is done then the symbol will not be put into :: or main::? I've thought of writing modules and so forth here, but then I truly get into different lexical scopes, which I'm trying to avoid for simplicity sake. (Read simplicity=50% laziness , 50% easy for non-perlers to understand). Thanks, dch.
        Importing the symbols into :: or main:: is exactly what I want (there is no package).

        You can still do that in a more conventional and only slightly more complex way by writing a proper module and exporting only what you really need to. Polluting main:: is just a bad idea in any case.

        Ideally what I want is #include "import.pl" but for reasons in the article above this isn't really there, unless you do some funky odd looking stuff with the DB module. I'd rather avoid funky odd looking stuff for this software as lots of people need to use and understand it. I do find it odd that an old C-coder like Larry W would choose not to give people the ability to #include.

        Perl's convention to include stuff is to use modules. There are appearently simpler alternatives on which use itself is actually built, and there are situations in which one may actually want to resort to them. For example in golf you may want to do a file. But you're not golfing. When wanting to use a module to be decided at runtime based upon some condition, then you want to require and manually import(). But that's not your case either. And so on...

        I've thought of writing modules and so forth here, but then I truly get into different lexical scopes, which I'm trying to avoid for simplicity sake. (Read simplicity=50% laziness , 50% easy for non-perlers to understand). Thanks, dch.

        Don't be misleaded by a wrong concept of simplicity. Do not aim for maximum simplicity, since chances are that it will bite you in the neck later on, revealing itself to only be appearently simple. I am aware of YAGNI, but there's stuff it's easy to know in advance YareGN, and even if it weren't so in some particular situation, it would in most common ones, thus getting the habit of doing so would raise the risk of making that into a bad programming habit. Aim for the Right® amount simplicity.

        Also, as Perl programmers we all know that Laziness is a cardinal virtue, but IMHO not really as of itself only.