in reply to 'if' pragma and modules with an empty import list

Hi

BEGIN { package G; $INC{q/G.pm/}=__FILE__; sub import { warn qq{@_ }; } } use G(); use G; use G; __END__ G at - line 1. G at - line 1.

As you can see import is only called twice when the empty parens aren't present

So if.pm does not know that the user didnt want import called

It might be possible to determine that using B::Deparse but that seems a bit much for a pragma

Replies are listed 'Best First'.
Re^2: 'if' pragma and modules with an empty import list
by kcott (Archbishop) on Apr 11, 2017 at 05:32 UTC

    G'day beech,

    "As you can see import is only called twice when the empty parens aren't present"

    I may be missing the point your trying to make here. I would only expect import() to be called twice (once for each 'use G;'). The empty list is intended to stop import() from being called.

    From use:

    If you do not want to call the package's import method (for instance, to stop your namespace from being altered), explicitly supply the empty list:

    use Module ();

    Although the arguments to use if are (CONDITION, MODULE, ()) — see the 'perl -MO=Deparse ...' line from my OP — I'm resonably sure the third argument (the empty list) is lost due to @_ being flattened; the version of @_, used by goto &work in if::import(), no longer has that empty list.

    Anyway, as I said, I think I may be missing some point you're making. If you'd care to clarify, I'd be happy to discuss further.

    — Ken

      Anyway, as I said, I think I may be missing some point you're making. If you'd care to clarify, I'd be happy to discuss further.

      Hi

      My point is that empty list , the parens , are not being lost, they never existed, and they can't be passed around, because foo() is the same as foo((),(),())

      Its a special case in the parser that causes use YADA (); to be treated as BEGIN{require YADA;} with no call to import.

      B::Deparse peeks at the optree to decide when to print use YADA();

      This is the parsing parts of a "use" statement

      https://perl5.git.perl.org/perl.git/blob/HEAD:/perly.y#l349

      349 | USE startsub 350 { CvSPECIAL_on(PL_compcv); /* It's a BEGI +N {} */ } 351 BAREWORD BAREWORD optlistexpr ';' 352 { 353 SvREFCNT_inc_simple_void(PL_compcv); 354 utilize($1, $2, $4, $5, $6); 355 parser->parsed_sub = 1; 356 $$ = NULL; 357 }

      toke.c s_tokenize_use

      Related loading module parts
      op.c Perl_vload_module
      op.c Perl_utilize

      6307 /* Fake up an import/unimport */ 6308 if (arg && arg->op_type == OP_STUB) { 6309 imop = arg; /* no import on explicit () */ 6310 }

      http://perldoc.perl.org/perlapi.html#load_module

      If you look inside sub begin_is_use inside B::Deparse ( L571 and L611 ) you can see what it goes through to decide if its dealing with a use statement with or without empty parens, its looking at the optree, because of the fake begin sub in utilize

      As you can see, the empty parens simply never existed

      Similar to my post above, but a weaker demonstration, if you look at perlrun there are two switches for loading modules

      $ perl -mopen -e 1 $ perl -Mopen -e 1 open: needs explicit list of PerlIO layers at -e line 0. BEGIN failed--compilation aborted.

      Passing no arguments (like empty parens) doesn't work with either version import gets called , because in the end its a simple use statement

      $ perl -Mopen= -e 1 open: needs explicit list of PerlIO layers at -e line 0. BEGIN failed--compilation aborted. $ perl -mopen= -e 1 open: needs explicit list of PerlIO layers at -e line 0. BEGIN failed--compilation aborted.

        ++ Thanks for the examples, code snippets and links. A fair amount of work has gone into that: much appreciated. And yes, I do now see the point you were making.

        — Ken