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

Maybe this is a more generic question than just Data::Dumper, but there is some odd behaviour that I don't understand. I thought that use statements were loaded at compile time, so why does this error:
use strict; use warnings; my %test_hash = ( a => { b=> 'c' } ); print Dumper %test_hash; use Data::Dumper;
I get the following error: print() on unopened filehandle Dumper Since Data::Dumper is loaded at compile time, why does the use statement matter where it is placed in the file?

Replies are listed 'Best First'.
Re: Order of 'use' statement in Data::Dumper
by psini (Deacon) on Jul 16, 2009 at 15:51 UTC

    When the parser sees the line "print Dumper %test_hash;", the Dumper sub has not been imported yet, so it treats it as a filehandle.

    I think that "print Dumper(%test_hash);" should work, but I'm too lazy to test it :).

    Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."

Re: Order of 'use' statement in Data::Dumper
by jrsimmon (Hermit) on Jul 16, 2009 at 15:51 UTC
    BEGIN blocks are processed at compile time, but use statements are subject to the flow of your code. In the example, as you've undoubtedly noticed, Data::Dumper is not available until execution has reached the use statement.
      Not true.
      use Data::Dumper;
      is the same as
      BEGIN { require Data::Dumper; Data::Dumper::->import(); }

      Like psini already said, the problem is that Perl already had to decide whether Dumper is a function call or not before use Dumper; was encountered.

      1. Compile my %test_hash = ( a => { b=> 'c' } );
      2. Compile print Dumper %test_hash; (Dumper is treated as a *Dumper since no function named Dumper was found)
      3. Compile use Data::Dumper;
      4. Execute require Data::Dumper;
      5. Execute Data::Dumper::->import();
      6. [ Script has been compiled. Now start executing it ]
      7. Execute my %test_hash = ( a => { b=> 'c' } );
      8. Execute print(*Dumper %test_hash);

      You can only omit parens on a function call to a function that's already been declared (but not necessarily defined) or if you annotate the function call with &.

      Update: Added list showing execution flow.

        Thanks all... it now makes sense...

      I don't think it is exactly so. When execution reach the print line, Data::Dumper is available. If you try the code from my previous example (I tested it, at last) you'll see that it works.

      The problem is that at compile time, the Dumper sub is not imported till use Data::Dumper is reached; so "print Dumper something", without parenthesis, is interpreted as if Dumper were a filehandle to print to.

      Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."

        That's true (and something I didn't know psini++), but I think the op was expecting
        use Module;
        to be equivalent with
        BEGIN{require Module;}
        , which it is not.