# from Aristotle Pagaltzis # on Sunday 10 August 2008 19:30: >>> See Tom Heady’s reply on this thread. >> >> Which also as issues, albeit maybe fewer. > >Yes, it will fail in some very rare cases. However, it does so loudly >and predictably.
Oh? 'chdir dirname( rel2abs( $0 ) );' doesn't look to me to contain the loud and predictable 'or die' >FindBin tries to avoid failing by employing >heuristics, and as we all know that is a fancy word for saying >“it doesn’t work.” I guess we like to call it a heuristic, because that makes it sound like we're solving some complicated and mathematically difficult problem? But "mistake" has fewer letters and doesn't imply that locating a directory somehow requires the Ramsey number for red six and blue six. In the case of Makefile.PL wanting to know where it is, I think anything involving rel2abs is probably overkill, and $0 could quite likely be incorrect on account of do(), so all you really want is dirname(__FILE__), right? Of course, if you're going to go through the loop of resolving symlinks, you do need to deal with things having been relative (assuming of course that what you wanted was to know the location of the file at the end of whatever number of symlinks (and that you didn't mind if a hardlink was involved because then we have to run find on the entire partition and compare inodes (which clearly FindBin should have done (but probably several steps after it checked -e $0, which it did not (but that would have been a nifty first step.))))) But in this particular case, does everything else in the world not already explode anyway unless(-e './Makefile.PL')? As for solving the generic case, you still have to account for PAR, and the fact that $0 might be '-e', or could simply be relative to wherever we were before a chdir(), at which point we should probably just exec('/usr/bin/eject', '.') in order to achieve suitable predictable loudness. But yes, the FindBin code is wrong, and so is the documentation. "If perl is invoked as C<perl filename> and I<filename> does not have executable rights and a program called I<filename> exists in the users C<$ENV{PATH}> which satisfies both B<-x> and B<-T> then FindBin assumes that it was invoked via the C<$ENV{PATH}>." Should have just said: "if $0 !~ m#/# and a program called ..." It seems like something using import() and caller() might generate a more predictable solution with fewer caveats (such as hating to be called twice, assuming $0, etc.) It could possibly even defer the symlink resolution bit until it was actually needed. use File::WhereAmI; my $where = File::WhereAmI->real_directory; my $there = File::WhereAmI->where_is_who("Bar.pm")->filename; But in Makefile.PL land, all of the necessary simplifying assumptions were made long ago. $ cd /tmp $ perl /wherever/Makefile.PL Could not open 'lib/Foo.pm': No such file or directory at .../ExtUtils/MM_Unix.pm line 2708. --Eric -- "Unthinking respect for authority is the greatest enemy of truth." --Albert Einstein --------------------------------------------------- http://scratchcomputing.com ---------------------------------------------------