in reply to Why am I getting "premature end of script header"?

use is evaluated at compile time, which eval can't catch. There are a few ways around this:
# Option 1 - string eval, test $@ eval "use HTTP::Request::Common"; if ($@) { # Missing } # Option 2 - string eval with return value of 1 if (eval "use HTTP::Request::Common; 1;") { # Loaded, good } else { # Missing } # Option 3 - require and import eval { require HTTP::Request::Common; HTTP::Request::Common->import; }; if ($@) { # Not found }
If I recall correctly option #2 is preferred.
  • Comment on Re: Why am I getting "premature end of script header"? - eval { use }
  • Download Code

Replies are listed 'Best First'.
Re^2: Why am I getting "premature end of script header"? - eval { use }
by lokiloki (Beadle) on Nov 27, 2006 at 22:40 UTC
    I just tried #2, or my interpretation of #2 and it didn't work... here is the code I used:
    #!/usr/bin/perl print "Content-type: text/html\n\n"; print "here we go again..."; if (eval "require LWP::UserAgent; use HTTP::Request::Common; 1 +;") { my $ua = LWP::UserAgent->new; my %post; my $content = $ua->request(POST "", +[%post])->as_string; print $content; } else { print "didnt work"; }
    And here is the error I got:
    ./ String found where operator expected at ./ line 10, near + "POST """ (Do you need to predeclare POST?) syntax error at ./ line 10, near "POST "http://www.cnn.c +om"" Execution of ./ aborted due to compilation errors.

      You must use parens around the arguments of a function call when the call is compiled before the function being called has been loaded.

      My solution doesn't suffer from that problem. It loads the function (i.e. the module) before the call to the function is compiled.

      So either add parens around the arguments for POST (and suffer from the loss of prototypes on all imported functions), or use what I already posted.

Re^2: Why am I getting "premature end of script header"? - eval { use }
by lokiloki (Beadle) on Nov 27, 2006 at 22:29 UTC
      This would be sufficient:
      BEGIN { if( eval "use fakemodule; 1;") { print STDERR "Loaded fakemodule"; } else { print STDERR "Couldn't load fakemodule."; } }
      Don't put BEGIN blocks inside a subroutine, they won't do what you want.

      Don't print in the BEGIN block, it will come before the Content-type header

      Calling a subroutine with the '&a' syntax has the following effects, from perlsub:

      • &NAME(LIST); # Circumvent prototypes.
      • &NAME; # Makes current @_ visible to called subroutine.
      In your code you used the &a; form, which would make the current @_ visible to the called subroutine. For example:
      first(1,2,3); sub first { &second; } sub second { print for @_; } # Output is 123
      Although it isn't relevant for this particular case it is still good to be aware of the prototype circumvention behaviour. Here is an example:
      use strict; use warnings; use Data::Dumper; sub pro(\@) { print Dumper \@_; } my @list = (1,2,3); pro(@list); &pro(@list);
      $VAR1 = [ [ 1, 2, 3 ] ]; $VAR1 = [ 1, 2, 3 ];
        thank you... so the takeaway message is that I should call subroutines via subroutine; and not &subroutine;? this must be a new thing? because the Perl book I have (admittedly the first edition o'reilly one) says that i should call subroutines with the ampersand...?