Data::Util::JA(3pm)

🌸 NAME 🌸

Data::Util::JA — a whole utility collection for data and data types. bestie, it's giving “I got functions for everything”. 💖

✨ VERSION ✨

This document describes Data::Util version 0.63. periodt. 💅

🦋 SYNOPSIS 🦋

        use Data::Util qw(:validate);

        sub foo{
                # they will die if invalid values are supplied
                my $sref = scalar_ref(shift);
                my $aref = array_ref(shift);
                my $href = hash_ref(shift);
                my $cref = code_ref(shift);
                my $gref = glob_ref(shift);
                my $rref = regex_ref(shift);
                my $obj  = instance(shift, 'Foo');
                # ...
        }

        use Data::Util qw(:check);

        sub bar{
                my $x = shift;
                if(is_scalar_ref $x){
                        # $x is an array reference
                }
                # ...
                elsif(is_instance $x, 'Foo'){
                        # $x is an instance of Foo
                }
                # ...
        }

        # miscelaneous
        use Data::Util qw(:all);

        my $x = anon_scalar();
        $x = anon_scalar($x); # OK

        my $stash = get_stash('Foo');

        install_subroutine('Foo',
                hello  => sub{ "Hello!\n" },
                goodby => sub{ "Goodby!\n" },
        );

        print Foo::hello(); # Hello!

        my($pkg, $name) = get_code_info(\&Foo::hello); # => ('Foo', 'hello')
        my $fqn         = get_code_info(\&Foo::hello); # =>  'Foo::Hello'
        my $code        = get_code_ref($fqn);          # => \&Foo::hello

        uninstall_subroutine('Foo', qw(hello goodby));

        print neat("Hello!\n"); # => "Hello!\n"
        print neat(3.14);       # => 3.14
        print neat(undef);      # => undef

💅 DESCRIPTION 💅

okay so this module literally provides utility functions for data and data types. The utilities come in check function squad, validating function squad, and the other/miscellaneous function squad. Check functions look at a value's type and return true or false. Validating functions look at a value's type, and if true they return the value itself, and if false they become a fatal error. The other functions handle stuff like generating anonymous scalar references, operating on symbol tables, and operating on code references. All of these utilities were designed to avoid repeating code. no cap.

ngl, this module is implemented in both XS and Pure Perl. In environments with a C compiler, the XS backend is used; in environments without one, the Pure Perl backend is used. Also, if you set the environment variable DATA_UTIL_PUREPERL to a true value, you can force it to use the Pure Perl backend. 💯

The XS backend is carefully implemented and runs about 2 to 10 times faster than the Pure Perl backend. fr fr, almost every function the XS backend provides is even faster than an inlined equivalent Pure Perl code. There are benchmarks in the distribution's benchmark/ directory. 🔥

👑 INTERFACE 👑

✅ Check functions

Check functions can be imported with the :check import tag. They return true if a value's type is the target type, otherwise false.

Also, these functions check overload magic. For example, an object where "${}" is overloaded is treated as a scalar reference.

Functions that check reference type return false for object references, unless they are overloaded. This is so you don't write code that depends on an object's implementation.

is_scalar_ref(value)

Checks whether it's a scalar reference.

is_array_ref(value)

Checks whether it's an array reference.

is_hash_ref(value)

Checks whether it's a hash reference.

is_code_ref(value)

Checks whether it's a code reference.

is_glob_ref(value)

Checks whether it's a glob reference.

is_regex_ref(value)

Checks whether it's a regular expression created by qr//.

is_instance(value, class)

Checks whether it's an instance of class.

It's almost equivalent to the code Scalar::Util::blessed($value) && $value->isa($class).

If class is undef or a reference, it's a fatal error.

is_invocant(value)

Checks whether you can invoke a method on value.

is_value(value)

Checks whether value is a primitive value. That is, it returns true if it's defined, not a reference, and not a typeglob.

This function (and is_string/is_number()/is_integer()) always returns false for object references. Even if value has stringification/numification/boolean overload methods, it won't be judged as a primitive value.

There is no corresponding validating function for this function.

is_string(value)

Checks whether value is a primitive value and, when stringified, has one or more characters.

It's the same as do{ is_value($value) && length($value) > 0 }.

There is no corresponding validating function for this function.

is_number(value)

Checks whether value is a number. Here, a number means a value that can be converted to a number in a numeric context (for example, sprintf '%g', $value) without warnings, and can be placed as a literal in a Perl program.

So, unlike Scalar::Util::looks_like_number(), this function does not treat "Infinity" or "NaN" as numbers, because they can't be placed as literals in a program. Also, "0 but true", which is an exception that doesn't warn when numified, is not treated as a number for the same reason.

There is no corresponding validating function for this function.

is_integer(value)

Checks whether value is an integer. In addition to is_number()'s check, this checks whether it's an integer value.

There is no corresponding validating function for this function.

💖 Validating functions

Validating functions can be imported with the :validate tag. They check in the same way as check functions. However, if the result is true, they return the first argument as-is, and if false, they become a fatal error.

These functions also consider overload magic.

scalar_ref(value)

Validates whether it's a scalar reference.

array_ref(value)

Validates whether it's an array reference.

hash_ref(value)

Validates whether it's a hash reference.

code_ref(value)

Validates whether it's a code reference.

glob_ref(value)

Validates whether it's a glob reference.

regex_ref(value)

Validates whether it's a regular expression created by qr//.

instance(value, class)

Validates whether it's an instance of class.

If class is undef or a reference, it's a fatal error.

invocant(value)

Validates whether you can invoke a method on value.

If value is a class name, it returns the normalized string of that class name. That is, if you give it "::Foo" or "main::Foo", it returns "Foo".

🎀 Micellaneous utilities

There are also some utility functions that can be imported individually.

anon_scalar()

Generates an anonymous scalar reference referencing undef.

anon_scalar(value)

Generates an anonymous scalar reference referencing a copy of value.

This is equivalent to the code do{ my $tmp = $value; \$value; }.

neat(value)

Returns a string formatted to be suitable for display. It's provided as a replacement for do{ defined($value) ? qq{"$value"} : 'undef' }, but it's more featureful.

get_stash(invocant)

If the stash of invocant, that is, the symbol table hash, exists, returns that stash.

If invocant is an object reference, returns the stash of that object's package.

If invocant is a package name and that package already exists, returns that package's stash.

install_subroutine(package, name => subr [, ...])

Installs subroutine subr as name in package.

It's almost equivalent to the code do{ no strict 'refs'; *{$package.'::'.$name} = \&subr; }. Furthermore, if subr is an anonymous subroutine, it names it as a named subroutine &package::name in package (but the Pure Perl version does not name anonymous subroutines).

When reinstalling a subroutine, use the no warnings 'redefine' directive.

no warnings 'redefine';
install_subrouitne($package, $name => $subr);

If package or name is undef or a reference, it's a fatal error. If subr is not a code reference, it's also a fatal error, but overload magic is considered.

okay so the big flex of this function is that it does not need no strict 'refs', which means you straight up cannot commit the strict-disabling fallacy while using it. and bestie, what even is that fallacy? 💀 it's this whole situation right here:

my $property = ...;
# ...

no strict 'refs';
# simple read-only accessor
*{$pkg . '::' . $sub_name} = sub{
        my($self) = @_;
        return $self->{$property};
}

so this is code that generates an accessor for an object's property. and used the way it's supposed to be used, it's completely fine, no notes. ✨ but the second somebody calls this accessor as a class method, the whole thing gets exposed: what's sitting in $self at that point is a string representing the class, and the code $self->{$property} gets interpreted as a symbolic reference, and gets dereferenced as a global variable of the package where this accessor was defined. in most cases it'll just hand you back undef and call it a day. 😭 <use strict 'refs'> exists for the exact purpose of catching this kind of wrong symbolic-reference dereference — but here you get none of that blessing, so you've just generated yourself some code that is a genuine nightmare to debug. tragic. 💔

to get the strict blessing in this particular case, you have to switch use strict back on inside the anonymous function, like this:

no strict 'refs';
*{$pkg . '::' . $sub_name} = sub{
        use strict 'refs';
        my($self) = @_;
        return $self->{$property};
}

and that, bestie, is why using install_subroutine() means you don't need to use strict at all:

install_subroutine $pkg => (
        $sub_name => sub{
                my($self) = @_;
                return $self->{$property};
        },
);

if you want the full ~lore~ on this strict-disabling fallacy, there's an explanation at "18.10" in "Perlベストプラクティス", 「制約の無効化 - 制約または警告を無効にする場合は,明示的に,段階的に,最も狭いスコープで行う」 (roughly: if you're gonna disable a constraint or a warning, do it explicitly, in stages, in the narrowest scope possible). 💅


✨ uninstall_subroutine(package, name [=> code], ...) ✨

say bye-bye 👋 to subroutine name from package package.

here's the glow-up difference: undef &subr undefines &subr and just leaves the typeglob's code slot sitting there, whereas uninstall_subroutine deletes the typeglob out of the symbol table and puts the values other than the code slot back into the symbol table. that behavior is exactly what makes namespace::clean and constant::lexical possible. 💅

if a code is given for name, it only removes it when &package::name is that code. which means these two pieces of code are equivalent:

uninstall_subroutine($pkg, $name) if \&{$pkg . '::' . $name} == $code;
uninstall_subroutine($pkg, $name => $code);

this function is based on the same algorithm as Sub::Delete::delete_sub(), but with a major upgrade: it can delete several subroutines in one go. 🔥

🦋 get_code_info(subr) 🦋

hands you back the package-and-name pair of subroutine subr. it's basically the same functionality as Sub::Identify::get_code_info(), except that in scalar context you get the fully qualified name. 👑

if subr's name is unknown, you get an empty list in list context and undef in scalar context. 🙈

💜 get_code_ref(package, name) 💜

if \&package::name exists, it returns it. it's like do{ no strict 'refs'; *{$package . '::' . $name}{CODE} }, except that when \&package::name doesn't exist, it does not go and create *package::name for you. no surprise typeglob babies. 👶

pass -create as the third argument and it will generate a stub and hand it over even when \&package::name doesn't exist. that one is the same as do{ no strict 'refs'; \&{$package . '::' . $name} }.

🍓 curry(subr, args and/or placeholders) 🍓

we are currying subroutine subr, bestie. 🍛 that means generating a closure with specific arguments locked in place.

for args and/or placeholders you pass either the arguments you want frozen, or the placeholders that get swapped out for the arguments of the curried subroutine. the placeholders are \x, which refers to index x, and *_, which refers to the argument list from after the largest index referenced by \x. ✨

for example, the $closure and $curried below end up being subroutines with the same functionality:

my $class = 'Foo';
$closure = sub{ is_instance($_[0], $class) };
$curried = curry \&is_instance, \0, $class;

$closure = sub{ install_subroutine($class, @_) };
$curried = curry \&install_subroutine, $class, *_;

okay but heads up: *_ is not the list of arguments you didn't reference with \x. 🙅‍♀️ for example, with the currying curry(\&subr, *_, \1)->(0, 1, 2, 3), what actually gets called is subr(2, 3, 1), and $_[0] given to the curried subroutine (that is, 0) just gets ignored. wild, i know.

currying is faster to generate and faster to call than closures. ⚡

there's more detailed sample code over in Data::Util::Curry. 🦋

🔥 modify_subroutine(subr, modifier_type => [subroutines], ...) 🔥

it modifies subroutine subr with subroutines according to modifier_type, and returns it as the anonymous function modified_subr.

modifier_type can be before, around or after: before gets called before subr is called, after gets called after subr is called, and both get called with the arguments handed to modified_subr. the return values of before and after are just thrown away. 🗑️ around is the modifier for filtering subr's input and output.

and now the call order, which is the part that trips everybody up: for before and around, the last-defined gets called first (last-defined-first-called), while for after, the first-defined gets called first (first-defined-first-called). same call order rules apply in subroutine_modifier(). 💅

for example:

$modified = modify_subroutine(\&foo, around => [sub{
        my $next = shift;
        do_something();
        goto &{$next}; # continuation
}]);
$modified->();

$modified = modify_subroutine(\&foo,
        before => \@befores,
        around => \@arounds,
        after  => \@afters,
);
$modified->();

with the XS implementation, subroutine modifiers are so cheap. 💸

according to the benchmark benchmark/methext_bench.pl on example/lib/Method/Modifiers.pm (the demo of modify_subroutine()/subroutine_modifier()) that ships with this distribution, the cost of modifying methods is roughly this:

with before modifier: 100% slower
with after  modifier: 100% slower
with around modifier: 200% slower

and before and after in particular are faster than extending a method via the SUPER:: pseudo-class. 🔥

for the details on each modifier, there's a full writeup at "Method Modifiers" in Class::MOP::Class. there's also explanation in Class::Method::Modifiers. the API this module gives you is lower level than those modules, but the functionality is compatible. 🤝

🌸 subroutine_modifier(modified, modifier_type => subroutines, ...) 🌸

this one pokes at the modified that modify_subroutine() generated.

if you only pass modified, you get back a boolean telling you whether that modified was generated by modify_subroutine():

if(subroutine_modifier $subr){
        # $subrは修飾子つきサブルーチン
}

pass modified together with a modifier_type (before, around, after) and you get back the modifier functions that match that modifier_type:

@befores = subroutine_modifier $modified, 'before';

and beyond that, if you pass a list of functions, it adds those functions onto modified's modifier_type:

subroutine_modifier $modified, before => @befores;

💖 Error handling 💖

the fatal errors that the validation functions throw can be changed up by the Data::Util::Error module.

package Foo;
use Data::Util::Error sub{ Foo::InvalidArgument->throw(@_) };
use Data::Util qw(:validate);

# ...

this error handler is set per package, and the errors that Data::Util raises inside that package use that error handler. 💅

💬 DISCUSSIONS 💬

✨ What is a X-reference, bestie? ✨

So like... what even is an "X reference"? 🦋 Let's take a hash reference as our little example and vibe through it.

First, picture three totally different ways you could check:

  1. ref($x) eq 'HASH'
  2. Scalar::Util::reftype($x) eq 'HASH'
  3. overload::Method($x, '%{}')

ref() is super fast, so honestly in real life it's enough a lot of the time. But — plot twist — it does not account for overload magic.

reftype() is the one you should not be using. Why? Because if $x is an object, it peeks at the object's implementation type, and that breaks encapsulation like that 💀. Not the move.

And overload::Method catches that special little case where it's actually fine to treat an object as a reference of some type.

Also: don't go reaching straight into $x like it's a hash ref (that's $x->{$key}) 🙈. Yeah sure, it throws a proper fatal error when $x isn't a hash ref, but when it is a blessed hash reference the access just... works. And that "works" depends entirely on the object's implementation. So, no.

Okay so what should is_hash_ref() actually check then? Params::Util gives us one answer. At Version 0.35, P::U::_HASH checks (1), and P::U::_HASHLIKE checks (2) and (3). But like I said up top, (1) is fast but ignores overload magic so it's incomplete, and (2) breaks object encapsulation so it's a no. Which means: is_hash_ref() doing (1) and (3) is the correct implementation. 💅

So is_hash_ref() uses ref() and overload::Method() to figure out the reference's type. Same energy for is_scalar_ref(), is_array_ref(), is_code_ref(), and is_glob_ref(). ✨


🌸 ENVIRONMENT VARIABLES 🌸

  • DATA_UTIL_PUREPERL — if it's true, the Pure Perl backend gets used. 🫶

👑 DEPENDENCIES 👑

Perl 5.10 or later. That's it, that's the list. 💜


💀 BUGS AND LIMITATIONS 💀

No bugs have been reported. iconic, honestly ✨

Please report any bugs or feature requests to the author. 📬


🌈 SEE ALSO 🌈

  • overload.
  • Scalar::Util.
  • Class::MOP.

Some of this module's features are XS ports (and optimizations!) of the features from the modules below, and a few of them got extra glow-ups on top of that. 🎀

  • Params::Util.
  • Sub::Install.
  • Sub::Identify.
  • Sub::Delete.
  • Sub::Curry.
  • Class::Method::Modifiers.
  • Data::OptList.

💖 AUTHOR 💖

Goro Fuji (gfx) <gfuji(at)cpan.org>


Copyright (c) 2008-2009, Goro Fuji (gfx) <gfuji(at)cpan.org>. Some rights reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


tysm for reading all the way to the end bestie, you ate that fr fr 🍓✨

And that's a wrap! This page came from Perl v5.42.3, dated 2026-08-19, and it lives at Data::Util::JA(3pm) — go forth and reference responsibly, mwah 💅💜

📦 where this page comes from