Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Cwd::abs_path or FindBin::Bin?

by Skeeve (Parson)
on Jun 05, 2019 at 06:34 UTC ( #11100985=perlquestion: print w/replies, xml ) Need Help??

Skeeve has asked for the wisdom of the Perl Monks concerning the following question:

What are you thoughts about using Cwd::abs_path() instead of $FindBin::Bin?

Motivation

In Mojolicious the auto-generated application script contains:

use FindBin; BEGIN { unshift @INC, "$FindBin::Bin/../lib" }

The issue I have with this is: $FindBin::Bin will not resolve a symbolic link. This can be fine in cases where you want to use different libraries with the same script. Simply create a symbolic link of the script to the location where your different libraries are.

But in my situation I simply wanted to create a symbolic link of the startscript to /usr/local/bin. Of course this is doomed to fail as I will end up with "/usr/local/bin/../lib". But the libraries are in "/app/myapp/lib".

So I've changed it now to

use Cwd 'abs_path'; BEGIN { unshift @INC, abs_path("$0/../../lib") }

Not only will it work in my situation, additionally the "relative part" gets resolved and the path added to @INC will be "/app/myapp/lib".

Questions

  1. Will it fail in any situation you can think of?
  2. Is there any disadvantage in using Cwd instead of FindBin?
  3. What are your thoughts on this matter?

s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
+.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e

Replies are listed 'Best First'.
Re: Cwd::abs_path or FindBin::Bin?
by haukex (Bishop) on Jun 05, 2019 at 07:18 UTC

    FindBin tries harder than $0 to resolve the path of the script, so I would always recommend the former.

    The issue I have with this is: $FindBin::Bin will not resolve a symbolic link.

    Sounds like you want $FindBin::RealBin instead.

      FindBin tries harder than $0 to resolve the path of the script

      But abs_path is taking care of resolving symlinks, isn't it? So is there still an issue?

      But anyhow: thanks for pointing me to RealBin.


      s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
      +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
        But abs_path is taking care of resolving symlinks, isn't it?

        Yes, but so is FindBin, with more effort and less code in your script - you can have a look at the source. Note it's been a core module for a long time.

        So is there still an issue?

        Not necessarily, if you are sure you'll always be running this script on this OS. But if you want portability, then you need to use the appropriate modules to ensure that, i.e. File::Spec or Path::Class. And personally I wouldn't use .. to remove the script's filename from the path (another advantage of $FindBin::Bin).

        # add a "lib" that is in the script's dir use File::Spec::Functions qw/catdir/; use lib catdir($FindBin::RealBin, 'lib'); # add a "lib" that is in the script's parent dir use Path::Class qw/dir/; use lib dir($FindBin::RealBin)->parent->subdir('lib')->stringify;

        You might also be interested in File::FindLib (although because that does a search, it is less deterministic).

Re: Cwd::abs_path or FindBin::Bin?
by ikegami (Pope) on Jun 08, 2019 at 10:32 UTC
    use FindBin qw( $RealBin ); use lib "$RealBin/../lib";
    is basically equivalent to
    use Cwd qw( abs_path ); use File::Basename qw( dirname ); use lib dirname(abs_path($0)) . "/../lib";

    (I don't know if the latter works on VMS.)


    Note that you should always use $RealBin. Using $Bin will cause your program to break if it's run via a symlink.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2020-10-01 16:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (16 votes). Check out past polls.

    Notices?