in reply to Re^4: Using import to generate subroutines
in thread Using import to generate subroutines

strict is a compile time pragma, it's effect is only on how the code in it's scope gets compiled, it doesn't do anything at runtime, so it will only be run once, even inside a loop. Actually now that I think of it any use statement only gets run once no matter where it is.

Before I realised that it's a use and so has no runtime effect, I did a bit of digging around in strict. The following might interest you.

If you look at

> perl -MO=Terse -e 'use strict;my @a;for my $f (@a){no strict "refs"; +print $$f}' LISTOP (0x8225988) leave [1] OP (0x831eec0) enter COP (0x8245398) nextstate OP (0x82258c8) padav [1] COP (0x831ee58) nextstate BINOP (0x831ee30) leaveloop LOOP (0x8232a98) enteriter [2] OP (0x82dc988) null [3] UNOP (0x8232a70) null [141] OP (0x823bc98) pushmark OP (0x823bce8) padav [1] UNOP (0x831ee10) null LOGOP (0x82dc9e8) and OP (0x82dc9a8) iter LISTOP (0x82dc960) lineseq COP (0x823c348) nextstate LISTOP (0x823c300) print OP (0x823c328) pushmark UNOP (0x8225880) rv2sv OP (0x82c1c20) padsv [2] OP (0x82dc9c8) unstack
you can't see any sign of the no strict 'refs'. It's not in the op tree and therefore doesn't do anything at runtime.

If you look in more detail and compare the output of

perl -MO=Debug -e 'use strict;my @a;for my $f (@a){no strict "refs";pr +int $$f}'
with
perl -MO=Debug -e 'use strict;my @a;for my $f (@a){print $$f}'
you will find (amongst other things) that the first contains
UNOP (0x83085c8) op_next 0x830b190 op_sibling 0x0 op_ppaddr PL_ppaddr[OP_RV2SV] op_targ 0 op_type 15 op_seq 7139 op_flags 6 op_private 1 op_first 0x8309088
and the second contains
UNOP (0x982ca28) op_next 0x981f960 op_sibling 0x0 op_ppaddr PL_ppaddr[OP_RV2SV] op_targ 0 op_type 15 op_seq 7128 op_flags 6 op_private 3 op_first 0x9835dd8

(I am far from an expert on these things by the way) RV2SV means Reference value 2 Scalar Value, this comes from $$f above. If you look in perl.h you'll find

#define HINT_STRICT_REFS 0x00000002 /* strict pragma */

This is used to turn on and off a flag in op_private.You can see that in the two debug dumps above, op_private is 1 for the no strict version and 3 for the all strict. This flag tells the interpreter whether the dereference should be checked for strictness when it's run. So here you can see exactly what the compile time effect of strict is.

Replies are listed 'Best First'.
Re^6: Using import to generate subroutines
by diotalevi (Canon) on Nov 24, 2004 at 23:35 UTC

    This is wrong. Strict subs and vars are compile time but strict refs are handled at runtime. Its used by the dereferencing opcodes so while you don't see an opcode for strict refs itself, it is still used. In fact, it can only be effective at runtime.

    Also, every time you say use ... you run the module's import() method. It happens at compile time but it certainly isn't a once-only thing.

    In regard to revdiablo's concern, the right thing to do is to put it inside the loop. It doesn't exert any additional overhead and definately should be used without having extra, confusing scopes.

      Of course they're checked at run time, as you say, it can only be effective at run time. I was simply pointing out that no strict 'refs' is not interpreted or executed at run time. The interpreter does not even know that there was such a line in the program, all it knows is that certain operations have had their strict refs bit set to 1 and others haven't. This was probably done using strict but it could also have been doneusing some of the B modules, there's no way to know.

      The point being that, for example this code

      print $$f; { no strict 'refs'; print $$f; print $$g; } print $$f;
      is not compiled down to a series of ops like
      print $$f; switch on the strict refs flag; print $$f; print $$g; switch off the strict refs flag; print $$f;

      Every dereference op has a flag on it to say whether it should be strict or not so it is in fact compiled down to something like

      print ( dereference $f allowing strings ); print ( dereference $f not allowing strings ); print ( dereference $g not allowing strings ); print ( dereference $f allowing strings );

      The no strict 'refs' does not perform any action at all at run time and so it's position relative to loops is irrelevant.

      Also, every time you say use ... you run the module's import() method. It happens at compile time but it certainly isn't a once-only thing.
      I'm not sure what your point is, I think you have misintepreted
      any use statement only gets run once no matter where it is

      All I meant by this was

      use MyModule; # this will be run once at compile time print "hello\n"; use MyModule; # this will be run once at compile time for (1..10) { use MyModule; # this will be run once at compile time print $_; }

      Each of the 3 use statements are run once only. If they were require statements then the 3rd one would be run 10 times because when you're dealing with require it does matter where it is.

        Ok, you're absolutely correct. I disagreed by accident. I though you had said something else.
Re^6: Using import to generate subroutines
by revdiablo (Prior) on Nov 25, 2004 at 01:04 UTC
    strict is a compile time pragma, it's effect is only on how the code in it's scope gets compiled, it doesn't do anything at runtime

    Ah, indeed. I erroneously thought the lexical effect was also a runtime effect. I stand corrected. Thanks for replying.