Scalar::Util(3)

πŸ“¦ version 1.650.0, in opensuse-leap 16.0

πŸ’… Scalar::Util β€” the manual page, but make it cute

okay bestie, you're looking at Scalar::Util(3) β€” a whole lil grab-bag of general-utility scalar subroutines. Yes, "scalar subroutines". Yes, that's the whole brand. Let's get into it ✨


🌸 SYNOPSIS

    use Scalar::Util qw(blessed dualvar isdual readonly refaddr reftype
                        tainted weaken isweak isvstring looks_like_number
                        set_prototype);
                        # and other useful utils appearing below

that's the import vibe. # and other useful utils appearing below β€” the module is literally telling you there's more, keep reading, we love a tease πŸ’…


πŸ¦‹ DESCRIPTION

So Scalar::Util is a collection of subroutines that people kept saying "ugh I wish this was in perl core" about. But like β€” the usage wasn't high enough to justify making them actual keywords, and each one is so tiny that shipping them as individual extensions would be wasteful. So they all moved in together. Roommates. It's giving commune 🏠

By default, though? Scalar::Util does not export any subroutines. None. Zero. You want them, you ask for them by name. Boundaries, honestly πŸ‘‘

✨ Core Perl builtin Functions

fun fact: lots of the functions in this module were the inspo for a whole new experimental facility in recent Perl versions. Starting from various development versions at 5.35.7, equivalent functions to many of these utilities live in the builtin:: package. glow-up arc 🌈

    use Scalar::Util qw(blessed);

    $class = blessed $obj;

    $class = builtin::blessed $obj;  # equivalent

For more info, go read the docs on builtin. iykyk πŸ“š


πŸ”₯ FUNCTIONS FOR REFERENCES

okay these ones all do useful little activities on reference values. group them together, they're a friend group 🫢

πŸ’– blessed

    my $pkg = blessed( $ref );

If $ref is a blessed reference, you get back the name of the package it's blessed into. Otherwise you get undef. that's the whole deal πŸŽ€

    $scalar = "foo";
    $class  = blessed $scalar;           # undef

    $ref    = [];
    $class  = blessed $ref;              # undef

    $obj    = bless [], "Foo";
    $class  = blessed $obj;              # "Foo"
⚠️ careful bestie β€” do not just use this as a truth test, like in if(blessed $ref)..., because the package name "0" is defined yet false. the way that would bite you 😭

Since Perl version 5.35.7 an equivalent function is available as builtin::blessed.

🌸 refaddr

    my $addr = refaddr( $ref );

If $ref is a reference, you get the internal memory address of the referenced value as a plain integer. Otherwise undef. it's just numbers, but make it fashion ✨

    $addr = refaddr "string";           # undef
    $addr = refaddr \$var;              # eg 12345678
    $addr = refaddr [];                 # eg 23456784

    $obj  = bless {}, "Foo";
    $addr = refaddr $obj;               # eg 88123488

Since Perl version 5.35.7 an equivalent function is available as builtin::refaddr.

πŸ¦‹ reftype

    my $type = reftype( $ref );

If $ref is a reference, you get the basic Perl type of the variable referenced, as a plain string (like "ARRAY" or "HASH"). Otherwise undef. no cap 🧚

    $type = reftype "string";           # undef
    $type = reftype \$var;              # SCALAR
    $type = reftype [];                 # ARRAY

    $obj  = bless {}, "Foo";
    $type = reftype $obj;               # HASH
πŸ“Œ heads up: for internal reasons, all precompiled regexps (qr/.../) are blessed references. So ref() returns the package name string "Regexp" on these, but reftype() will return the underlying C structure type of "REGEXP" in all capitals. plot twist πŸ’€

Since Perl version 5.35.7 an equivalent function is available as builtin::reftype.

πŸ’… weaken

    weaken( $ref );

The lvalue $ref gets turned into a weak reference. Which means: it will not hold a reference count on the object it references. And also β€” when the reference count on that object hits zero, the reference gets set to undef. This function mutates the lvalue you passed as its argument and returns no value. it does the thing and leaves, iconic 🫑

Super useful for keeping copies of references without preventing the object from being DESTROY-ed at its usual time.

    {
      my $var;
      $ref = \$var;
      weaken($ref);                     # Make $ref a weak reference
    }
    # $ref is now undef
⚠️ big one: if you take a copy of a scalar with a weakened reference, the copy will be a strong reference. sneaky!!
    my $var;
    my $foo = \$var;
    weaken($foo);                       # Make $foo a weak reference
    my $bar = $foo;                     # $bar is now a strong reference

And this gets even less obvious elsewhere, like in grep(), for instance when you're grepping through a list of weakened references to objects that may already be destroyed:

    @object = grep { defined } @object;

This will indeed remove all references to destroyed objects, but β€” plot twist β€” the remaining references to objects will be strong, causing those remaining objects to never be destroyed, because there's now always a strong reference to them in the @object array. not me accidentally leaking 😭

Since Perl version 5.35.7 an equivalent function is available as builtin::weaken.

πŸ’œ unweaken

    unweaken( $ref );

Since version 1.36.

The lvalue REF gets turned from a weak reference back into a normal (strong) reference again. This function mutates the lvalue you passed as its argument and returns no value. It literally undoes what weaken did. undo button energy ↩️

It's slightly neater and more convenient than this otherwise-equivalent code:

    my $tmp = $REF;
    undef $REF;
    $REF = $tmp;

...because in particular, simply assigning a weak reference back to itself does not work to unweaken it. $REF = $REF does not work. fr fr, it just doesn't πŸ™ˆ

Since Perl version 5.35.7 an equivalent function is available as builtin::unweaken.

πŸŽ€ isweak

    my $weak = isweak( $ref );

Returns true if $ref is a weak reference. vibe check on your reference πŸ’«

    $ref  = \$foo;
    $weak = isweak($ref);               # false
    weaken($ref);
    $weak = isweak($ref);               # true
πŸ“Œ NOTE: copying a weak reference creates a normal, strong, reference.
    $copy = $ref;
    $weak = isweak($copy);              # false

Since Perl version 5.35.7 an equivalent function is available as builtin::is_weak.


⭐ OTHER FUNCTIONS

the rest of the squad, no theme, just vibes πŸ’«

πŸ“ dualvar

    my $var = dualvar( $num, $string );

Returns a scalar that has the value $num in a numeric context and the value $string in a string context. two-faced in the most slay way possible πŸ‘‘

    $foo = dualvar 10, "Hello";
    $num = $foo + 2;                    # 12
    $str = $foo . " world";             # Hello world

🌈 isdual

    my $dual = isdual( $var );

Since version 1.26.

If $var is a scalar that has both numeric and string values, the result is true.

    $foo = dualvar 86, "Nix";
    $dual = isdual($foo);               # true

Note that a scalar can be made to have both string and numeric content through standard operations:

    $foo = "10";
    $dual = isdual($foo);               # false
    $bar = $foo + 0;
    $dual = isdual($foo);               # true

The $! variable is commonly dual-valued, though it's also magical in other ways:

    $! = 1;
    $dual = isdual($!);                 # true
    print("$!\n");                      # "Operation not permitted"
🚨 CAUTION: this function is not as useful as it may seem. Dualvars are not a distinct concept in Perl β€” they're a standard internal construct of all scalar values. Almost any value could be considered a dualvar by this function through the course of normal operations. so like... temperamental king πŸ’€

🧚 isvstring

    my $vstring = isvstring( $var );

If $var is a scalar which was coded as a vstring, the result is true.

    $vs   = v49.46.48;
    $fmt  = isvstring($vs) ? "%vd" : "%s"; #true
    printf($fmt,$vs);

🌸 looks_like_number

    my $isnum = looks_like_number( $var );

Returns true if perl thinks $var is a number. See "looks_like_number" in perlapi. perl's opinion, honestly 🫢

πŸ¦‹ openhandle

    my $fh = openhandle( $fh );

Returns $fh itself β€” if $fh may be used as a filehandle and is open, or if it's a tied handle. Otherwise undef is returned.

    $fh = openhandle(*STDIN);           # \*STDIN
    $fh = openhandle(\*STDIN);          # \*STDIN
    $fh = openhandle(*NOTOPEN);         # undef
    $fh = openhandle("scalar");         # undef

πŸ’œ readonly

    my $ro = readonly( $var );

Returns true if $var is readonly. hands off bestie 🚫

    sub foo { readonly($_[0]) }

    $readonly = foo($bar);              # false
    $readonly = foo(0);                 # true

πŸŽ€ set_prototype

    my $code = set_prototype( $code, $prototype );

Sets the prototype of the function given by the $code reference β€” or deletes it if $prototype is undef. Returns the $code reference itself. it gives you back what you gave it, polite ✨

    set_prototype \&foo, '$$';

πŸ’… tainted

    my $t = tainted( $var );

Returns true if $var is tainted. contamination check 🦠

    $taint = tainted("constant");       # false
    $taint = tainted($ENV{PWD});        # true if running under -T

🩺 DIAGNOSTICS

Using the module may give you one of these errors during import. yes, during import, before you even get to the party πŸ™ƒ

  • Vstrings are not implemented in this version of perl β€” the version of perl you're using does not implement Vstrings. To use isvstring you'll need to use a newer release of perl. time to update, bestie 😭

πŸ’€ KNOWN BUGS

There's a bug in perl5.6.0 with UV's that are >= 1<<31. It shows up as tests 8 and 9 of dualvar.t failing. ancient lore, but we respect the archive 🏺


πŸ‘€ SEE ALSO

  • List::Util

the sibling module. family πŸ’–


Copyright (c) 1997-2007 Graham Barr <gbarr@pobox.com>. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Additionally weaken and isweak, which are:

Copyright (c) 1999 Tuomas J. Lukka <lukka@iki.fi>. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as perl itself.

Copyright (C) 2004, 2008 Matthijs van Duin. All rights reserved. Copyright (C) 2014 cPanel Inc. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


and that's the page!! 🫢 this whole thing is from perl v5.42.0, dated 2024-08-07, and it's the Scalar::Util(3) manpage β€” go forth and bless your references, bestie πŸ’œβœ¨

πŸ“¦ where this page comes from