in reply to When is "use module" not the same as require+import?

Not exactly. The documentation says:

It is exactly equivalent to
BEGIN { require Module; Module->import( LIST ); }

And the BEGIN{} block makes all the difference. The BEGIN means that the code is run immediately after Perl has reached the closing curly brace. Which is well before Perl runs the code that initializes your @fields array. Putting the assignment to @fields into a(nother) BEGIN block would alleviate that problem.

Replies are listed 'Best First'.
Re^2: When is "use module" not the same as require+import?
by AZed (Monk) on Sep 18, 2008 at 19:23 UTC

    Whee, except that comes with the additional interesting quirk that you can't actually declare the array in the BEGIN, because of course it will go out of scope between that block and the fresh BEGIN block implicit in use. What a mess. Looks like require+import is actually cleaner-looking.

    Thanks, both to you and moritz below, since the versioning issue is also good to know.

      It seems that you can get around the scoping issue by not leaving the BEGIN block:
      BEGIN { my @fields = qw/field1 field2/; use fields @fields; } my $self = fields::new; $self->{field1} = 'value1';
      works just fine for me. It may fairly be argued that this is not much different from putting a require and import inside the BEGIN, though.

      UPDATE: ikegami correctly points out that I must not have tested what I thought I tested, because this code doesn't work. Sorry. I think Bloodnok's solution (adapted to use fields) works, though.

        BEGIN { my @fields = qw/field1 field2/; use fields @fields; }
        is equivalent to
        BEGIN { my @fields = qw/field1 field2/; BEGIN { require fields; fields->import(@fields); } }
        which is compiled and executed as follows:
        1. my @fields = qw/field1 field2/; is compiled
        2. require fields; is compiled
        3. fields->import(@fields); is compiled
        4. require fields; is executed
        5. fields->import(@fields); is executed
        6. my @fields = qw/field1 field2/; is executed

        As you can see, an empty array is passed to the module. I believe you were mistaken when you claimed it worked.

      An alternative to get round the scoping problem is...
      use vars qw/%a_hash/; BEGIN { $a_hash{key} = qw/val/; } . .
      A user level that continues to overstate my experience :-))