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

Hello fellow Monks,

I just stumbled about a little curiousity (I see it that way) when trying to require a Modul. I use:
eval { require SomeModul }; return 0 if ($@);
This is triggered by a button event in a GUI. But when I now fix the compile error in this Modul and try it a second time (without restarting the GUI), my script crashes. Is this correct? Maybe I have done something wrong, so I was wondering if other people can give me a hint on this and maybe a way to do it right.
I use wxPerl for the GUI and I have produced this error with Perl 5.8.8 under WinXP
Humble,

Andre

Replies are listed 'Best First'.
Re: Require a Modul that produced a error before
by ikegami (Patriarch) on Oct 12, 2006 at 17:54 UTC

    require won't do anything the second time around since the module has been marked as included the first time around (even though it didn't load completely).

    You could clear the %INC entry on failure, but that could lead to very odd (i.e. hard to debug) errors.

    eval { require Module }; print $@ ? "Error\n" : "Success\n"; # Error { local $, = ", "; local $\ = "\n"; print keys %INC; } eval { require Module }; print $@ ? "Error\n" : "Success\n"; # Success
    # Module.pm for;
      What did you ment by:
      "You could clear the %INC entry on failure, but that could lead to very odd (i.e. hard to debug) errors."
      I tested it and so far it worked.
      Is it safe to use it, or not ? Are there any other things that maybe can be reverted ? Would you use it ? Where can I find additional sources, that I can take a look at ?

      It would only be needed for development, but if it produced odd errors I cant use it.

      Thanks so far,

      Andre

        Sorry for the delayed reply.

        In the examples below, I used the following test harness:

        my $module = do { open(my $fh, '<', 'Module.pm') or die("Unable to read Module.pm: $!\n"); local $/; <$fh> }; eval $module or warn $@; $module =~ s/^for;$/#for;/m; eval $module or warn $@;
        • The most common problem would be (safely ignored) warnings.

          use strict; use warnings; package Module; sub one { } for; sub two { } 1;

          First require/eval output:

          [None]

          Second require/eval output:

          Subroutine one redefined at (eval 2) line 6.
        • Another problem is code running twice.

          use strict; use warnings; package Module; END { print("END1\n"); } for; END { print("END2\n"); } 1;

          First require/eval output:

          [None]

          Second require/eval output:

          END2 END1 END1
        • Same, but different.

          use strict; use warnings; package Module; BEGIN { print("BEGIN1\n"); } for; BEGIN { print("BEGIN2\n"); } 1;

          First require/eval output:

          BEGIN1

          Second require/eval output:

          BEGIN1 BEGIN2
        • Objects can be created and destroyed twice.

          use strict; use warnings; package Module; { package Obj; sub new { print "Creating\n"; bless({}, shift) } sub DESTROY { print "Destroying\n"; } } our $o; BEGIN { $o = Obj->new(); } for; 1;

          First require/eval output:

          Creating

          Second require/eval output:

          Subroutine new redefined at (eval 2) line 8. Subroutine DESTROY redefined at (eval 2) line 9. Creating Destroying Destroying

          Hopefully, nothing took the address of $o in between the two requires!

        That's all I can think of. It's not quite as bad as I thought, since I thought a function could capture a variable from the first attempt, and another function could capture the same variable from the second attempt. Still, the above can still create some weird problems.