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

In Conway's "Object-Oriented Perl" he does this:
package X; $VERSION = 12; use strict;
as a means to avoid having to package-qualify $VERSION but I thought that the assignment to $VERSION was at runtime but the effect of the use strict was at compile-time.

Replies are listed 'Best First'.
Re: is use strict a compile time directive?
by davorg (Chancellor) on Oct 16, 2001 at 15:18 UTC

    Yes, the use strict happens at compile time. But its effects are lexically scoped.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you don't talk about Perl club."

Re (tilly) 1: is use strict a compile time directive?
by tilly (Archbishop) on Oct 16, 2001 at 16:16 UTC
    davorg already nailed it, but I would like to point out that the above item is checked at compile time. Try it
    use strict; print "This is executed at run-time\n"; $undeclared_var = "this will be caught";
    This is important because it allows typos to be caught even if they are along execution paths your program didn't take in testing. (Catch errors early and all that.)

    In fact the strict vars, and strict subs checks are both compile time. But checking refs is a run-time issue, and propagation to eval is also a run-time issue. So the compile-time declaration has some run-time and some compile time effects.

    If you want a fuller explanation of how strict.pm works, you can try Re (tilly) 1: How does strict work?.

Re: is use strict a compile time directive?
by TheDamian (Vicar) on Oct 18, 2001 at 16:15 UTC
    BTW, nowadays I'd suggest writing that as:
      package X;
      use strict;
      our $VERSION = 13;
    
    in the (admittedly unlikely) event that you don't have to worry about backwards compatibility with 20th Century perls.
      I asked this question at Why is 'our' good?, and I have looked through a number of discussions of the feature.

      Not one has left me with the feeling that our is really a good addition to the language.

      Perhaps there is something basic that I am missing, but it really seems to me to be a misfeature. For instance in this example just reversing the order is conceptually simpler and doesn't declare $VERSION to be in the current package (even overriding further package declarations). Even aside from the backwards compatibility issue, those facts are more compelling to me than the convenience issue for the occasional case wehre I want to have multiple packages declared in the same file. (Which is the only advantage to our that I see.)

      Am I missing something?

        Am I missing something?

        Avoiding use vars and being able to give package variables associated types (our Dog $spot) wasn't enough to convince you?

        Well, perhaps my new Attributes::Filtered module will be. Once it's available, by using our you'll be able to declare package variables (or parts of package variables, such as individual hash entries) with attributes.

        I have a great reason for not using our. I don't have the luxury of assuming that all of my code is going to run on 5.6.x..

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you don't talk about Perl club."

      I've only lately convinced the sysadmins here to upgrade from 5.004 (which hasn't actually happened yet). I've had a private installation of 5.6.1 for my own use, but anytime I run h2xs to create a module, I take out the 'our's and put in 'use vars'.
Re: is use strict a compile time directive?
by broquaint (Abbot) on Oct 16, 2001 at 15:40 UTC
    Doesn't this also make scripts with use strict a *little* slower to run as it has more to do i.e without it Perl can go about it's merry way without having to check the code, and then runs until it comes across something unmistakably foolish. Or am I barking up the wrong pragma?
    INOAA

    broquaint

    P.S That's 'In Need Of An Answer' BTW ;o)

      I don't know which way it works out, but my answer is that it would be a horrible reason to not use strict.pm.

      Sure, the (generally compile-time) checks that strict.pm invokes have to take some time. But the types of coding practices it discourages take more time at run-time. (Yes, it is faster to access a lexical variable than a global.) So it is hard to say which way the fraction of the second is going to go.

      However there is no question that on any significant script you will save development time with strict.pm. And there is also no question that as a developer it is very important to come to understand that premature optimization is bad. So the question of how strict.pm plays out performance-wise is irrelevant to me, and should be irrelevant to any decent Perl programmer. The difference is small, it speeds development, and it assists in writing correct programs.

      That is more than enough reasons to use it.

        I totally agree that leaving out use strict for the sake of speed is a bad thing(tm) and would never actually commit such a blasphemy myself. I merely wonder for the sake of furthering my Perl knowledge, and hoped to make the point you can always get a bit more speed if you're feeling a little mad. Leaving out use strict is about as useful as loop flattening and infinitely more dangerous (said ominously). Sorry if I've given anyone bad ideas, and yes, 'the voices' are generally wrong.
        HTH

        broquaint

      Strict 'vars' and strict 'subs' are compile-time directives, so they don't apply as others pointed out.

      Avoiding strict refs for speed? Ack! Pttht!

      A quick walk thorugh the source reveals that way down in the bowels of op.c, Perl_ck_rvconst is the function checking strict 'refs'. The section reads:

      if ((PL_hints & HINT_STRICT_REFS)&&(kid->op_private & OPpCONST_BARE)){ char *badthing = Nullch; switch (o->op_type) { case OP_RV2SV: badthing = "a SCALAR"; break; case OP_RV2AV: badthing = "an ARRAY"; break; case OP_RV2HV: badthing = "a HASH"; break; } if (badthing) Perl_croak(aTHX_ "Can't use bareword (\"%s\") as %s ref while \"strict refs\" + in use", name, badthing); }
      So we've got a a bitwise AND (and a pointer deref) going on to see if we've got something that might throw a stricture error. If there's no strict, we skip this next part.

      Next, we've got a switch statement with three possibilities: we wanted a SCALAR, ARRAY or HASH reference. That'll compile down to something tight and small (three comparisons, a jump-table of some kind, etc...). Only if any of these match does badthing get set and the error thrown.

      So at the very worst case that doesn't actually throw an error you've got:

      • A bit-AND you'd have to do anyway.
      • A C pointer deref and another bit-AND
      • Up to three additional comparison operations
      • Moving a pointer
      • And a dereference of one more pointer.
      (Your mileage will vary greatly, I'm sure.)

      So if you're worried about a small number of ANDs, pointer moving and comparisons to check for strict because you're looking for speed: look elsewhere. There's nothing to optimize here.