I tested my solution from a module too and it's unlikely such a chdir happens at compile time before a module is used.

Especially since a BEGIN { chdir ".." } also effects relative paths in @INC.

Granted I was too lazy posting two files.

So I'd speculate this approach is good enough for the OPs cases.

Modules can be loaded at run time. And that will break any code that relies on a constant working directory.

Load a simple module at run time from a simple script and have the module report where the main script is:

/tmp/perlmonks>cat run.pl #!/usr/bin/perl use strict; use warnings; use lib '/tmp/perlmonks'; # Tons of work omitted ... ;-) @ARGV and chdir '/tmp/unrelated'; require Mod; Mod::where(); /tmp/perlmonks>cat Mod.pm package Mod; use v5.12; # for say use strict; use warnings; use FindBin; sub where { say "Script is in $FindBin::Bin"; say "Script basename is $FindBin::Script"; say "Real script directory is $FindBin::RealBin"; say "Real script basename is $FindBin::RealScript"; say "Module was loaded from $INC{'Mod.pm'}"; } 1; /tmp/perlmonks>perl run.pl Script is in /tmp/perlmonks Script basename is run.pl Real script directory is /tmp/perlmonks Real script basename is run.pl Module was loaded from /tmp/perlmonks/Mod.pm /tmp/perlmonks>

That works even from the command line:

/tmp/perlmonks>perl -MMod -e Mod::where Script is in /tmp/perlmonks Script basename is -e Real script directory is /tmp/perlmonks Real script basename is -e Module was loaded from Mod.pm /tmp/perlmonks>

Run the script again, but this time, change the working directory before loading the module:

/tmp/perlmonks>perl run.pl x Cannot find current script 'run.pl' at /usr/share/perl5/FindBin.pm lin +e 166. BEGIN failed--compilation aborted at /usr/share/perl5/FindBin.pm line +166. Compilation failed in require at /tmp/perlmonks/Mod.pm line 6. BEGIN failed--compilation aborted at /tmp/perlmonks/Mod.pm line 6. Compilation failed in require at run.pl line 11. /tmp/perlmonks>

Obviously, FindBin has some tests to prevent accidents, but they can be defeated:

/tmp/perlmonks>touch /tmp/unrelated/run.pl /tmp/perlmonks>perl run.pl Script is in /tmp/unrelated Script basename is run.pl Real script directory is /tmp/unrelated Real script basename is run.pl Module was loaded from /tmp/perlmonks/Mod.pm /tmp/perlmonks>

Now, FindBin is sure that the main script is /tmp/unrelated/run.pl. It is not.

To fix that problem, load FindBin as early as possible from the main script, or even via command line parameters:

/tmp/perlmonks>perl -MFindBin run.pl x Script is in /tmp/perlmonks Script basename is run.pl Real script directory is /tmp/perlmonks Real script basename is run.pl Module was loaded from /tmp/perlmonks/Mod.pm /tmp/perlmonks>

Oh, by the way, this is not the problem from the FindBin documentation. FindBin documents a different problem, with persistent environments like mod_perl:

KNOWN ISSUES

If there are two modules using FindBin from different directories under the same interpreter, this won't work. Since FindBin uses a BEGIN block, it'll be executed only once, and only the first caller will get it right. This is a problem under mod_perl and other persistent Perl environments, where you shouldn't use this module. Which also means that you should avoid using FindBin in modules that you plan to put on CPAN.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

In reply to Re^4: Do modules know the callers full path? by afoken
in thread Do modules know the callers full path? by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.