in reply to Re^2: When C<use Module;> is *not* the same as C<require Module; import Module;>?
in thread When C<use Module;> *not* the same as C<require Module; import Module;>?

You forgot to wrap in BEGIN {}.

#! perl -slw #use HTTP::Status; BEGIN { require HTTP::Status; import HTTP::Status; } print RC_FORBIDDEN; __DATA__ P:\test>test4 ## This is with c<use> 403 P:\test>test4 ## This is with require/import but no BEGIN Name "main::RC_FORBIDDEN" used only once: possible typo at P:\test\tes +t4.pl line 5. print() on unopened filehandle RC_FORBIDDEN at P:\test\test4.pl line 5 +. P:\test>test4 ## This is with require/import inside BEGIN 403

Updated to add complete code listing with output.

  • Comment on Re^3: When C<use Module;> *not* the same as C<require Module; import Module;>?
  • Download Code

Replies are listed 'Best First'.
Re^4: When C<use Module;> *not* the same as C<require Module; import Module;>?
by BrowserUk (Patriarch) on Jan 08, 2005 at 16:53 UTC
    You forgot to wrap in BEGIN {}

    No, that was deliberate. There would be no point in not using use if I did. The whole point is to defer the loading of the module until and if it is needed.

    As constants are subs, and Perl allows you to call a sub that hasn't been declared yet, it is possible to use the constants in your code prior to them having been loaded. The bit I was missing, as merlyn pointed out above, is that it won't be recognised as a constant sub without having been previously declared or, I use the brackets().


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
      No, that was deliberate. There would be no point in not using use if I did. The whole point is to defer the loading of the module until and if it is needed.

      That's exactly the problem. Some of the benefits of "use"ing a module can only be observed when it is done at compile time. This is particularly important when prototypes are involved. For example, the Test::Exception module uses prototypes to allow you to use this syntax:

      dies_ok {$foo->method1} 'expecting to die'; For one of my modules, I wanted to use Test::Exception in an eval so that I could skip the tests if Test::Exception was not installed. It didn't work (with the syntax shown above) until I wrapped the eval in a BEGIN block.

        That's one (of an ever extending list) of reasons that I dislike both the concept and implementation, and so do not use, the Test::* suite of modules.

        Test code should not itself impose additional runtime constraints and requirements. If it does, then you end up having to write testcode to test the testcode as well as the testcode to test the code under test.

        Testing is good. But in my opinion, and I realise that many (most?) will disagree with me, most of the mechanisms I've seen used for performing testing of Perl, and particularly those of the Test::* suite of modules I've looked at, are too invasive and impose too many constraints, requirements and dependancies.

        That's not a well-formed or properly elaborated explaination. Maybe I'll get around to thinking it through properly and writing it up one day.


        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.
        For one of my modules, I wanted to use Test::Exception in an eval so that I could skip the tests if Test::Exception was not installed. It didn't work (with the syntax shown above) until I wrapped the eval in a BEGIN block.

        For those who don't already know, you can always call prototyped subroutines that take a bare block with () and an explicit sub {} if you want.

        I've made this more explicit in the documentation of T::E for those who hate prototypes.

      I overlooked that this was about conditionally loading the module somewhere between the OP and the post about HTTP::Status.

      #! perl -slw # This would normally be updated based on some condition in the code. my $condition = 0; # possibly very many lines of code go here # Faking a condition in the code... $condition ||= shift @ARGV; if ($condition) { require HTTP::Status; import HTTP::Status; print RC_FORBIDDEN(); # as merlyn pointed out, we need to give the +parser a clue } __END__ P:\test>test4 0 P:\test>test4 1 403
      This was really for my benefit and no one elses.