Raku Land




# export Bin() and Script() by default.

use FindBin;

my $dir_from    = Bin();        # $dir_from is an IO object
my $script_base = Script();     # $script_base is a string.

# explicitly export only Bin() or Script().

use FindBin :Bin;
use FindBin :Script;

# set verbose or resolve to True by default in the current
# lexical scope.
# caller can examine constants
#   MY::_FindBin-verbose-def
#   MY::_FindBin-resolve-def
# to determine the default.
# verbose output is sent to stderr via "note" with a 
# leading '#'.

use FindBin :verbose;
use FindBin :resolve;
use FindBin ( :verbose :resolve );

# request the bin path with symlinks resolved
# regardless of the default at use time.
# Bin will have symlinks along the path resolved,
# Script will return the basename of any resolved
# symlink.

my $resolved    = Bin( :resolve  );

# determine if the current executable is running
# from a symlinked path. stringy compare of the
# IO objects does the right thing.

my $dir         = Bin( :!resolve );
my $abs         = Bin( :resolve  );

$dir ne $abs
and say "There is a symlink in path '$dir'";

# make every subsequent call to Bin() default to
# Bin( :resolve )
# within the current lexical scope.

use FindBin :resolve;

# messages might be useful for dealing with
# stray symlinks in filesystem.

my $dir_from    = Bin( :verbose );

# make every subsequent call to Bin() default to Bin(:verbose)
# within the current lexical scope.

use FindBin :verbose;


This module is used to locate the currently running Raku program and the diretory it is running from.

Command-line use of raku -, raku -e or interactive use of the REPL will cause Script() to return "-", "-e", or "interactive" and Bin() to return $*CWD.

Otherwise Script() will return the basename of the running program and Bin() will return the name of the directory where the program was run from (taken from $*PROGRAM when Bin is called).


The IO returned by Bin will allways be an absolute (i.e., rooted) path via .absolute or or .resolve. In most cases the absolute path is more useful: people created the symlinks for a reason; resolve is mainly useful for code performing validation or analysis of things like dangling links.

The stringy path can be extracted calling ~Bin() or Bin.Str.

Arguments to Bin() & Script():

Causes Bin() to return the bin value after resolving symliks with .resolve instead of .absolute.

Turns on verbose reporting (to STDERR) for debugging purposes, including the path used, resolve status, and returned value.

Defaults via use FindBin

The defaults for both arguments can be set in the current lexical context by passing the options to use FindBin statement. For example:

# make Bin() default to Bin(:resolve)
use FindBin :Bin, :resolve;

# alternatively, make Bin() default to Bin(:resolve, :verbose)
use FindBin :Bin, :resolve, :verbose;

Note that explicitly passing a :!resolve or :!verbose to Bin() will override these defaults:

use FindBin :verbose;

my $dir = Bin( :!verbose ); # runs without logging

To see examples of using :resolve with symlinks look at the test t/10-symlink.t.


Class which implements the dirname, basename, and absolute methods use to determine the absolute path returned by Bin().


https://docs.raku.org/routine/absolute https://docs.raku.org/routine/resolve

Imitation really is the sincerest form of flattery. Kindly take a moment to notice how many thing that made sense and just plain worked were contributed to Perl by Graham Barr. Then flatter him: produce something that works equally well in Raku.


Steven Lembark lembark@wrkhors.com


Copyright 2018-2020 Steven Lembark

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0 or any later version.