Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

__FILE__ fails in app built with PAR::Packer

by metaperl (Curate)
on Sep 09, 2011 at 22:45 UTC ( #925167=perlquestion: print w/ replies, xml ) Need Help??
metaperl has asked for the wisdom of the Perl Monks concerning the following question:

NEW SIMPLE EXAMPLE

I'm updating this node with a very simple test case that demonstrates the problem and does not require Mojolicious:
# works in plain perl # fails with this compilation line: # pp -P -r -v 99 -o packed.pl somefile.pl BEGIN { use File::Spec; for (@INC) { if ( !ref $_ && -d $_ && !File::Spec->file_name_is_absolute($_ +) ) { $_ = File::Spec->rel2abs($_); } } } sub hello { my $file = __FILE__; warn "My file name is $file. Here is my contents:"; open(my $fh, "<", $file); my @data = <$fh>; warn "@data"; } hello(); 1;

OLD NODE

With the latest Mojolicious from CPAN, if you use PAR::Packer to create an executable for webapp.pl by running pack.pl (by cloning this repo) then Mojolicious::Controller will fail to find the template directory because it uses this code to do so:
my $T = File::Spec->catdir(File::Basename::dirname(__FILE__), 'templat +es');
Because PAR::Packer-based executables run out of a temp directory, the relative path returned by __FILE__ is not found. Changing line 21 to
my $T = File::Spec->catdir(File::Basename::dirname($INC{'Mojolicious/L +ite.pm'} || __FILE__), 'templates');
results in the binary version of webapp.pl running successfully.

good questions, no answer yet

The author of Mojolicious asked a good question regarding my described symptoms:
18:18 <@sri> even if it's in a temporary directory why would __FILE__ return the wrong file?

related nodes

this person did not run into this problem for some reason

Comment on __FILE__ fails in app built with PAR::Packer
Select or Download Code
Re: __FILE__ fails in Mojolicious app built with PAR::Packer
by Anonymous Monk on Sep 10, 2011 at 04:38 UTC

    No, __FILE__ does not fail

    __FILE__ is not guaranteed to be an absolute path (use lib '.'), or a real file (-e)

    If __FILE__ is relative, and something does chdir, __FILE__ will point to the wrong thing

    You could argue it is a bug to rely on __FILE__ as always being absolute

    I would argue it is a bug to put relative paths into @INC/%INC

    See chdir and relative paths in @INC

    BEGIN { use File::Spec; for (@INC) { if ( !ref $_ && -d $_ && !File::Spec->file_name_is_absolute($_ +) ) { $_ = File::Spec->rel2abs($_); } } }
      If __FILE__ is relative, and something does chdir, __FILE__ will point to the wrong thing
      I noticed you said *if* __FILE__ is relative. When is it relative and when not? A simple program I wrote to trip up __FILE__ yields an absolute path for some reason:
      sub hello { chdir '..'; my $file = __FILE__; warn "My file name is $file. Here is my contents:"; open(my $fh, "<", $file); my @data = <$fh>; warn "@data"; } hello(); 1;
      Maybe there is something wrong with the chdir, I am doing to keep my Mojolicious::Lite app working under PAR::Packer... perhaps ... I will meditate on this a bit more.
      You could argue it is a bug to rely on __FILE__ as always being absolute
      Yes, I also think it's a less-than-appealing that __FILE__ is not always absolute, dont you? And when is __FILE__ computed? Runtime? compiletime? How is it done?
      I would argue it is a bug to put relative paths into @INC/%INC See chdir and relative paths in @INC
      Yes. Thank you for that data. That could save me a few hours of debugging at some point. However, the whole topic of loading files and relative paths on @INC is tangential to the issue with __FILE__, correct?

      I tried putting the @INC fixing code at the top of a script demonstrating the __FILE__ problem with PAR and still have the anomaly when using PAR. What chdir command might fix this? I will meditate on that right after this post.

      # works in plain perl, fails with this compilation line: # pp -P -r -v 99 -o packed.pl somefile.pl BEGIN { use File::Spec; for (@INC) { if ( !ref $_ && -d $_ && !File::Spec->file_name_is_absolute($_ +) ) { $_ = File::Spec->rel2abs($_); } } } sub hello { my $file = __FILE__; warn "My file name is $file. Here is my contents:"; open(my $fh, "<", $file); my @data = <$fh>; warn "@data"; } hello(); 1;
Re: __FILE__ fails in app built with PAR::Packer
by Anonymous Monk on Sep 10, 2011 at 22:38 UTC

    See ppselfdoc.PL, PAR::Environment#PAR_0, perlsyn#Plain Old Comments (Not!)

    http://search.cpan.org/dist/PAR-Packer/MANIFEST
    http://search.cpan.org/src/RSCHUPP/PAR-Packer-1.010/contrib/docs/where_is_it.txt
    http://search.cpan.org/src/RSCHUPP/PAR-Packer-1.010/contrib/docs/who_am_i.txt

    What par ends up running is %PAR_TEMP%\f5cabe72.pl

    package main; shift @INC; #line 1 "script/main.pl" if (defined $ENV{PAR_APP_REUSE}) { warn "Executable was created without the --reusable option. See 'p +erldoc pp'.\n"; exit(1); } my $zip = $PAR::LibCache{$ENV{PAR_PROGNAME}} || Archive::Zip->new(__FI +LE__); my $member = eval { $zip->memberNamed('script/__FILE__.925167.pl') } or die qq(main.pl: Can't open perl script "script/__FILE__.925 +167.pl": No such file or directory ($zip)); PAR::_run_member($member, 1);

    And %PAR_TEMP%\0e790715.pl

    package main; shift @INC; #line 1 "script/__FILE__.925167.pl" # works in plain perl # fails with this compilation line: # pp -P -r -v 99 -o packed.pl __FILE__.925167.pl BEGIN { use File::Spec; for (@INC) { if ( !ref $_ && -d $_ && !File::Spec->file_name_is_absolute($_ +) ) { $_ = File::Spec->rel2abs($_); } } } sub hello { my $file = __FILE__; warn "My file name is $file. Here is my contents:"; open(my $fh, "<", $file); my @data = <$fh>; warn "@data"; } hello(); 1;
    Compare with %PAR_TMP%\inc\lib\strict.pm
    #line 1 "strict.pm" package strict;

    In an earlier par version it was

    #line 1 "C:/perl/5.10.1/lib/strict.pm" package strict;

    So yeah, those #line number "file" directives have gotten out of sync with reality and evolved into uselessness, as have the values in %INC  strict.pm => /loader/HASH(0xaa240c)/strict.pm

    This decision isn't explained anywhere

    I don't see any reason for those values not to be absolute paths, esp the %INC values

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://925167]
Approved by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2014-12-29 16:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (194 votes), past polls