Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
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 chilling in the Monastery: (17)
As of 2015-07-02 17:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (44 votes), past polls