NAME

Util::Underscore - Common helper functions without having to import them

VERSION

version v1.4.2

SYNOPSIS

use Util::Underscore;
_::croak "$foo must do Some::Role" if not _::does($foo, 'Some::Role');

DESCRIPTION

This module contains various utility functions, and makes them accessible through the _ package. This allows the use of these utilities (a) without much per-usage overhead and (b) without namespace pollution.

How do they differ from Perl's builtin die and warn? The error messages of die and warn are located on the line where the exception is raised. This makes debugging hard when the error points to some internal function of a module you are using, as this provides no information on where your client code made a mistake. The Carp family of error functions report the error from the point of usage, and optionally provide stack traces. If you write a module, please use the Carp functions instead of plain die.

Additionally, the variants _::carpf, _::cluckf, _::croakf, and _::confessf are provided. These take a sprintf patterns as first argument: _::carpf "pattern", @arguments.

To handle errors, the following keywords from Try::Tiny are available:

_::try

_::catch

_::finally

They are all direct aliases for their namesakes in Try::Tiny.

Miscellaneous Functions

$fh = _::is_open $fh

wrapper for Scalar::Util::openhandle

$str = _::prototype \&code

_::prototype \&code, $new_proto

gets or sets the prototype, wrapping either CORE::prototype or Scalar::Util::set_prototype

$start_from_level: The level starting from which frames should be constructed. For example, 1 would start from the immediate caller, whereas 0 includes the current frame as well. If ommited, uses 1.

returns: A list of Util::Underscore::CallStackFrame objects.

$stack_frame = _::caller

$stack_frame = _::caller $level

Assembles an object representing a specific call stack frame.

$level: The level of which the call stack frame is to be returned. A value of 1 would return the immediate caller, whereas 0 would indicate the current frame. If ommited, uses 1.

returns: A Util::Underscore::CallStackFrame instance representing the requested stack frame. If no such frame exists, undef is returned.

For invoking external commands, Perl offers the system command, various modes for open, and the backtick operator (qx//). However, these modes encourage interpolating variables directly into a string, which opens up shell injection issues. In fact, open and system can't avoid shell injection when piping or redirection is involved. The IPC::Run module avoids this by offering a flexible interface for launching and controlling external processes.

$success = _::process_run COMMAND_SPEC

Spawns the specified command(s), and blocks until completion.

COMMAND_SPEC: An IPC::Run harness specification.

returns: A boolean indicating whether all spawned processes completed without errors (all sub-processes have exit code zero). This is inverse to Perl's built in system function!

RATIONALE

Context and Package Name

There are a variety of good utility modules like Carp or Scalar::Util. I noticed I don't import these (in order to avoid namespace pollution), but rather refer to these functions via their fully qualified names (e.g. Carp::carp). This is ultimately annoying and repetitive.

This module populates the _ package (a nod to JavaScript's Underscore.js library) with various helpers so that they can be used without having to import them, with a per-usage overhead of only three characters _::. The large number of dependencies makes this module somewhat heavyweight, but it avoids the “is any in List::Util or List::MoreUtils”-problem.

In retrospect, choosing the _ package name was a mistake: A certain part of Perl's infrastructure doesn't recognize _ as a valid package name (although Perl itself does). More importantly, Perl's filetest operators can use the magic _ filehandle which would interfere with this module if it were intended for anything else than fully qualified access to its functions. Still, a single underscore is less intrusive than some jumbled letters like Ut::any.

Scope and Function Naming

This module collects various utility functions that – in my humble opinion – should be part of the Perl language, if the main namespace wouldn't become too crowded as a result. Because everything is safely hedged into the _ namespace, we can go wild without fearing name collisions. However, a few naming conventions were adhered to:

Functions with a boolean return value start with is_.

If the source module already provided a sensible name, it is kept to reduce confusion.

As a valued partner and proud supporter of MetaCPAN, StickerYou is
happy to offer a 10% discount on all Custom Stickers,
Business Labels, Roll Labels,
Vinyl Lettering or Custom Decals. StickerYou.com
is your one-stop shop to make your business stick.
Use code METACPAN10 at checkout to apply your discount.