Scalar::Does(3pm)

πŸ’… Scalar::Does β€” like ref() but, like, actually useful

okay bestie so this is a User Contributed Perl Documentation page, and it's for a Perl module called Scalar::Does ✨ no cap, it's giving "the does() builtin Perl always deserved."


🌸 SYNOPSIS 🌸

use Scalar::Does qw( -constants );

my $object = bless {}, 'Some::Class';

does($object, 'Some::Class');   # true
does($object, '%{}');           # true
does($object, HASH);            # true
does($object, ARRAY);           # false

πŸ¦‹ DESCRIPTION πŸ¦‹

So real talk: people have been saying forever that Perl would be so much better with a built-in does(). Because like… doing ref($thing) eq 'ARRAY' means you can't accept an object that uses overloading to fake an array-ish interface. πŸ™ˆ Rude, honestly. So this module is here to fix that.

✨ Functions ✨

does($scalar, $role)

Checks if a scalar is capable of performing the given role. Here's the tea on the predefined roles (and yes, they're case-sensitive, don't try to be cute):

  • SCALAR or ${} β€” checks if the scalar can be used as a scalar reference.
Heads up bestie: this role does not check whether a scalar is a scalar (which is, like, obviously true). It checks whether it's a reference to another scalar. Different thing!! πŸ’€
  • ARRAY or @{} β€” checks if the scalar can be used as an array reference.
  • HASH or %{} β€” checks if the scalar can be used as a hash reference.
  • CODE or &{} β€” checks if the scalar can be used as a code reference.
  • GLOB or *{} β€” checks if the scalar can be used as a glob reference.
  • REF β€” checks if the scalar can be used as a ref reference, i.e. a reference to another reference. referenceception πŸŒ€
  • LVALUE β€” checks if the scalar is a reference to a special lvalue (like, say, the result of substr or splice).
  • IO or <> β€” uses IO::Detect to check if the scalar is a filehandle or a filehandle-like object.
    • (the <> check is slightly looser, allowing objects which overload <> β€” though overloading <> well can be a little tricky, iykyk 🫠)
  • VSTRING β€” checks if the scalar is a vstring reference.
  • FORMAT β€” checks if the scalar is a format reference.
  • Regexp or qr β€” checks if the scalar can be used as a quoted regular expression.
  • bool β€” checks if the scalar can be used as a boolean. (it's pretty rare for this to not be true, ngl)
  • "" β€” checks if the scalar can be used as a string. (also pretty rare for this to not be true)
  • 0+ β€” checks if the scalar can be used as a number. (again, pretty rare for this to not be true)
Note that this is far looser than looks_like_number from Scalar::Util. For example: an unblessed arrayref can be used as a number (it numifies to its reference address); and the string "Hello World" can be used as a number (it numifies to 0). wild, right? 😭
  • ~~ β€” checks if the scalar can be used on the right hand side of a smart match.

So here's how the delegation works, and this part is important:

  • If the given role is blessed and provides a check method, then does delegates to that. πŸ’«
  • Otherwise, if the scalar being tested is blessed, then $scalar->DOES($role) gets called, and does returns true if that method call returned true.
  • If the scalar being tested looks like a Perl class name, then $scalar->DOES($role) is also called, and the string "0E0" is returned for success β€” which evaluates to 0 in numeric context but true in boolean context. sneaky iconic behavior πŸ‘‘

does($role)

Called with a single argument, it tests $_. And yes bestie, this works with lexical $_. we love to see it πŸ₯Ή

given ($object) {
   when(does ARRAY)  { ... }
   when(does HASH)   { ... }
}
Note: in Scalar::Does 0.007 and below, the single-argument form of does returned a curried coderef. This was changed in Scalar::Does 0.008. so if you're on ancient versions, that's why ur confused πŸ’€

overloads($scalar, $role)

A function overloads (which just checks overloading, as the name suggests) is also available.

overloads($role)

Called with a single argument, it tests $_. Yes, this works with lexical $_.

Note: in Scalar::Does 0.007 and below, the single-argument form of overloads returned a curried coderef. This was changed in Scalar::Does 0.008.

blessed($scalar), reftype($scalar), looks_like_number($scalar)

For convenience, this module can also re-export these functions from Scalar::Util. And honestly? looks_like_number is generally more useful than does($scalar, q[0+]). fr fr.

make_role $name, where { BLOCK }

Returns an anonymous role object which you can use as a parameter to does. The block is arbitrary code which should check whether $_[0] does the role. build ur own, main character energy πŸ”₯

where { BLOCK }

Syntactic sugar for make_role. Compatible with the where function from Moose::Util::TypeConstraints, so don't worry about conflicts. bestie behavior, honestly 🫢

πŸŽ€ Constants πŸŽ€

The following constants may be exported for convenience:

  • SCALAR
  • ARRAY
  • HASH
  • CODE
  • GLOB
  • REF
  • LVALUE
  • IO
  • VSTRING
  • FORMAT
  • REGEXP
  • BOOLEAN
  • STRING
  • NUMBER
  • SMARTMATCH

🌈 Export 🌈

By default, only does is exported. This module uses Exporter::Tiny, so functions can be renamed:

use Scalar::Does does => { -as => 'performs_role' };

Scalar::Does also plays some tricks with namespace::clean to ensure that any functions it exports to your namespace get cleaned up when you're finished with them. Why do we care? Because if you're writing object-oriented code, does and overloads will not be left hanging around as methods of your classes. Moose::Object provides a does method, and you should be able to use Scalar::Does without interfering with that. no drama, no collisions, periodt. πŸ’…

You can import the constants (plus does) using:

use Scalar::Does -constants;

The make_role and where functions can be exported like this:

use Scalar::Does -make;

Or list specific functions/constants that you wish to import:

use Scalar::Does qw( does ARRAY HASH STRING NUMBER );

πŸ’œ Custom Role Checks πŸ’œ

use Scalar::Does
  custom => { -as => 'does_array', -role => 'ARRAY' },
  custom => { -as => 'does_hash',  -role => 'HASH'  };

does_array($thing);
does_hash($thing);

look at u, making ur own role checks. obsessed. 😌


πŸ’€ BUGS πŸ’€

Please report any bugs to <http://rt.cpan.org/Dist/Display.html?Queue=Scalar-Does>. (yes, that's a link, and yes, we're telling you about it instead of making it clickable, it's a manpage bestie, we work with what we've got)


πŸ‘‘ SEE ALSO πŸ‘‘

🧚 Relationship to Moose roles

Scalar::Does is not dependent on Moose, and its role-checking is not specific to Moose's idea of roles β€” but it does work well with Moose roles. ✨

Moose::Object overrides DOES, so Moose objects and Moose roles should just work with Scalar::Does.

{
  package Transport;
  use Moose::Role;
}

{
  package Train;
  use Moose;
  with qw(Transport);
}

my $thomas = Train->new;
does($thomas, 'Train');          # true
does($thomas, 'Transport');      # true
does($thomas, Transport->meta);  # not yet supported!

Mouse::Object should be compatible enough to work as well.

See also: Moose::Role, Moose::Object, UNIVERSAL.

πŸ“ Relationship to Moose type constraints

Moose::Meta::TypeConstraint objects, plus the constants exported by MooseX::Types libraries, all provide a check method β€” so again, should just work with Scalar::Does. Type constraint strings are not supported however. noted. πŸ’€

use Moose::Util::TypeConstraints qw(find_type_constraint);
use MooseX::Types qw(Int);
use Scalar::Does qw(does);

my $int = find_type_constraint("Int");

does( "123", $int );     # true
does( "123", Int );      # true
does( "123", "Int" );    # false

Mouse::Meta::TypeConstraints and MouseX::Types should be compatible enough to work as well.

See also: Moose::Meta::TypeConstraint, Moose::Util::TypeConstraints, MooseX::Types, Scalar::Does::MooseTypes.

⭐ Relationship to Type::Tiny type constraints

Types built with Type::Tiny and Type::Library can be used exactly like Moose type constraint objects above. ✨

use Types::Standard qw(Int);
use Scalar::Does qw(does);

does(123, Int);   # true

In fact, Type::Tiny and related libraries are used extensively in the internals of Scalar::Does 0.200+.

See also: Type::Tiny, Types::Standard.

πŸŽ€ Relationship to Role::Tiny and Moo roles

Roles using Role::Tiny 1.002000 and above provide a DOES method, so they should work with Scalar::Does just like Moose roles. Prior to that release, Role::Tiny did not provide DOES. so like, check ur version bestie πŸ’…

Moo's role system is based on Role::Tiny.

See also: Role::Tiny, Moo::Role.


🫢 AUTHOR 🫢

Toby Inkster <tobyink@cpan.org>. (iconic.)


This software is copyright (c) 2012-2014, 2017 by Toby Inkster.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. slay. 🌈


🌸 DISCLAIMER OF WARRANTIES 🌸

THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

(translation: no promises bestie, it's giving "as is" energy πŸ’€)


and that's the whole page!! πŸ’–βœ¨πŸŽ€ This was <rainbow>perl v5.40.1</rainbow>, dated 2025-08-04, and the page itself is Scalar::Does(3pm) β€” go forth and does() responsibly, my love πŸ¦‹πŸŒΈπŸ’œ

πŸ“¦ where this page comes from