Module:...::Array(3)

๐Ÿ“ฆ version 1.1.3, in alpine 3.24

๐Ÿ’… Module:...::Array(3) โ€” user contributed perl documentation, bestie โœจ

okay so this is the manual page for Module:...::Array(3), and it's genuinely iconic. it's giving "object-oriented array manipulation" and we're gonna get through it together. no cap. ๐Ÿซถ


๐ŸŒธ NAME ๐ŸŒธ

Module::Generic::Array โ€” an Array Manipulation Object Class ๐Ÿ’–


โœจ SYNOPSIS โœจ

bestie. there is SO much here. but every single line matters, so here's the whole thing exactly as it is, no skipping, no summarising, periodt:

    my $ar = Module::Generic::Array->new( [qw( Joe John Mary )] );
    printf( "There are %d people\n", $ar->length );
    my $object = $ar->as_array; # returns the array object
    my $str = $ar->as_string; # Joe John Mary
    my $hash = $ar->as_hash; # Joe => 0, John => 1, Mary => 2
    my $hash = $ar->as_hash( start_from => 2 ); # Joe => 2, John => 3, Mary => 4
    my $lines = Module::Generic::Array->new( \@lines );
    $lines->chomp; # Now @lines does not contain any \n at the end
    my $ar2 = $ar->clone;
    $ar->contains( 'Joe' ); # true
    # Same as splice:
    my $removed = $ar->delete( 'John', 1 ); # 'John' is returned
    $removed->length; # 1
    my @removed = $ar->delete( 'John', 1 );
    $ar->each(sub
    {
        print( "I got $_\n" );
        # could also write:
        # print( "I got $_[1] at offset $_[0]\n" );
        $ar->break; # stop looping
    });
    $ar->empty; # $ar is now empty
    # Same as contains:
    $ar->exists( 'Mary' ); # true
    my $even = $ar->even; # Joe Mary
    $ar->first; # Joe
    $ar->for(sub
    {
        my( $i, $val ) = @_;
        # do something
    });
    $ar->foreach(sub
    {
        my $val = shift( @_ );
        # do something
    });
    $ar->get(2); # Mary
    my $elements = $ar->grep(sub{ $_ eq 'John' });
    $elements->length; # 1
    my @elements = $ar->grep(sub{ $_ eq 'John' });
    my $elements = $ar->grep(qr/^Jo/);
    $elements->length; # 2
    my @elements = $ar->grep(qr/^Jo/);
    # Same as exists:
    $ar->has( 'Mary' ); # true
    # Get 'Mary' in object context
    print $ar->index(2)->substr( 0, 2 ); # Ma
    my $name = $ar->index(2);
    print "Name is: $name\n"; " Name is: Mary
    my $it = $ar->iterator;
    print $it->next; # Joe
    print "Names are: ", $ar->join( ', ' ), "\n"; # Names are: Joe, John, Mary
    print $ar->keys->as_string, "\n"; # 0 1 2
    print $ar->last->substr( 0, 2 ); # Ma
    $ar->length; # 3 (because there are 3 elements in the array object)
    my @people = $a->list; # @people now is ( "Joe", "John", "Mary" )
    print( $a->map(sub{ $_->value })->join( "\n" ), "\n" );
    my $a = Module::Generic::Array->new( [qw( Jack John Peter )] );
    my $b = Module::Generic::Array->new( [qw( Gabriel Raphael Emmanuel )] );
    $a->merge( $b );
    print( $a->join( ' ' ), "\n" ); # Jack John Peter Gabriel Raphael Emmanuel

    my $a = Module::Generic::Array->new( [qw( 1 2 3 4 5 6 7 8 9 10 )] ); my
    $odd = $a->odd; say "@$odd"; # 2 4 6 8 10

    my $a = $m->new_array( [qw( Jack John Peter Gabriel Raphael Emmanuel )] );
    print( $a->offset( 2, 3 )->join( ' ' ), "\n" ); # John Peter Gabriel

    my $a = Module::Generic::Array->new( [qw( Hello world )] );
    # called in object context
    say $a->pop->length; # 5 (returns a Module::Generic::Scalar in object context)
    # but
    say $a->pop; # returns "world" as a regular string

    my $a = Module::Generic::Array->new( [qw( John Jack Peter )] );
    my $offset = $a->pos( 'Jack' ); # returns 1
    $a->pos( 'Bob' ); # Returns undef
    my $hash = { first_name => 'John', last_name => 'Doe' };
    $a->push( $hash );
    $a->pos( $hash ); # Returns 3

    my $a = Module::Generic::Array->new( [qw( John Jack Peter )] );
    my $b = Module::Generic::Array->new( [qw( Gabriel Raphael Emmanuel )] );
    $a->push( $b ); # or you can do $a->push( $b->list );
    # Now $a contains something like: John Jack Peter Module::Generic::Array=ARRAY(0x557d2c2983e8)
    # Equally
    $a->merge( $b ); # $a now is: John Jack Peter Gabriel Raphael Emmanuel

    my $ar = Module::Generic::Array->new( [qw( John Joe Mary )]);
    $ar->push_arrayref( [qw( Jack Peter )] );
    print( $ar->join( "," ), "\n" );
    # Now prints: John, Joe, Mary, Jack, Peter

    my $dummy = { class => 'Hello' };
    my $a = Module::Generic::Array->new( ['Jack', 'John', $dummy, 'Paul', 'Peter', 'Gabriel', 'Raphael', 'Emmanuel'] );
    $a->remove( $dummy, qw( John Paul Peter Emmanuel ) );
    say( "@$a" ); # Jack Gabriel Raphael

    $ar->reset; # Now the array object is empty

    $ar->for(sub
    {
        my( $i, $n ) = @_;
        $pos = $n;
        $b->for(sub
        {
            my( $j, $v ) = @_;
            # Tell loop for array $a to stop
            $a->break if( $n == 7 && $v == 27 );
        });
        # some more stuff here....
    });

    my $a = Module::Generic::Array->new( [qw( Jack John Peter Paul Gabriel Raphael Emmanuel )] );
    $a->for(sub
    {
        my( $i, $n ) = @_;
        # tell it to skip Peter
        $a->return(+1) if( $n eq 'John' );
        # No need to return a true value anymore
        # Ending the loop must be explicitly expressed using break
    });

    $ar->reverse; # Mary John Joe

    $ar->scalar; # 3 (returns the size of the array object)

    $a->set( qw( John Jack Peter ) ); # Using an array of elements
    $a->set( [qw( John Jack Peter )] ); # Using an array reference of elements
    $a->set( $a2 ); # Using another array object, whatever its class may be

    my $a = Module::Generic::Array->new( [qw( Hello world )] );
    say $a->shift->length; # 5
    # but
    say $a->shift; # returns "Hello" as a regular string

    $ar->size; 2 (size of the array object starting from 0)

    $ar->sort; Joe John Mary

    my $a = Module::Generic::Array->new( [qw( I disapprove of what you say, but I will defend to the death your right to say it )] );
    say $a->splice( 7, 3 ); # returns a list containing "I", "will", "defend"
    say $a->splice( 7 ); # returns a list containing "I", "will", "defend", "to", "the", "death", "your", "right", "to", "say", "it"

    say a->splice( 7, 3 )->length; # returns 3 obviously
    say a->splice( 7 )->length; # returns 11

    my $a = $ar->split( qr/[[:blank:]\h]+/, "I disapprove of what you say, but I will defend to the death your right to say it" );
    $a->length; # 18
    # or in list context and using the method as a class method
    my @words = Module::Generic::Array->split( qr/[[:blank:]\h]+/, "I disapprove of what you say, but I will defend to the death your right to say it" );

    $ar->undef; # same as reset. Now the array object is empty

    my $dummy = { class => 'Hello' };
    my $a = Module::Generic::Array->new( ['Jack', 'John', $dummy, 'Paul', 'Peter', 'Gabriel', $dummy, 'Peter', 'Raphael', 'Emmanuel'] );
    my $b = $a->unique;
    # $b now contains: 'Jack', 'John', $dummy, 'Paul', 'Peter', 'Gabriel', 'Raphael', 'Emmanuel'
    # or to update $a directly (in place):
    $a->unique(1);

    $ar->unshift( qw( Peter Gabriel ) ); # Now array is Peter Gabriel Joe John Mary

    $ar->values; # Peter Gabriel Joe John Mary

    # Adding one more
    $ar->push( "Jack" );

๐Ÿฆ‹ VERSION ๐Ÿฆ‹

v2.3.0 โ€” slay, current era. โœจ


๐ŸŽ€ DESCRIPTION ๐ŸŽ€

the whole point of this class/package is literally to give you an object-oriented approach at array manipulation. that's the vibe. that's the mission. ๐Ÿ’…


๐Ÿ‘‘ METHODS ๐Ÿ‘‘

okay bestie, method time. here's the lore, one by one. ๐Ÿ”ฅ

๐ŸŒˆ new

provided with an optional array reference or an array object such as Module::Generic::Array, this will create a new object and return it. easy. iconic. ๐Ÿซถ

๐Ÿ“ append

this is an alias for push. same energy, different name. ๐Ÿ’–

๐ŸŒธ as_hash

returns an hash reference with the keys being the array elements and the hash values their offset value. yes bestie, keys are the elements, values are the offsets. ๐ŸŽ€

it takes an optional hash of options:

  • start_from โ€” if true, the offset values will start from the number provided and not 0, as it is the case by default.

example, because we love a visual:

    my $a = Module::Generic::Array->new( [qw( Jack John Peter )] );
    my $h = $a->as_hash({ start_from => 1 });
    # $h now is:
    {
        Jack => 1,
        John => 2,
        Peter => 3,
    }

๐Ÿฆ‹ as_array

this simply returns the current object, so it does nothing special. it is here, so that one can blindly call as_array on any of the Module::Generic::Array, Module::Generic::Boolean, Module::Generic::Number or Module::Generic::Scalar object and get an Module::Generic::Array object in return. honestly? convenient king behaviour. ๐Ÿ‘‘

โœจ as_string

returns the array as string, which is essentially the same as "@array". no cap. ๐Ÿซถ

it takes an optional boolean value that, if true, will sort the array before.

๐Ÿ’… break

instructs the loop of the given object to exit the loop. the way that this works is lowkey cute โ€” you can return on the call of break to immediately exit any loop you are in. for example:

    $a->for(sub
    {
        # Do something
        return( $a->break ) if( $true );
        # And something more
    });

it also works if you are within another loop, because break returns a code that exit the current loop as well. for example:

    $a->for(sub
    {
        # Do something
        $b->foreach(sub
        {
            # Now exit the $b loop and the $a loop as well
            return( $a->break ) if( $true );
            # And something more
        });
    });
warning bestie: it will not work though if you are in 3 loops deep. that's the limitation for now. ๐Ÿ˜ญ for example:
    $a->for(sub
    {
        # Do something
        $b->foreach(sub
        {
            $c->foreach(sub
            {
                # Now exit the $c loop and the $a loop only at the end of the $b loop iteration
                return( $a->break ) if( $true );
                # And something more
            });
        });
    });

๐Ÿงš callback

sets or gets a callback on the array object. you can set 2 types of callback: add or remove which will be called respectively when you add something to the array or when you remove something from it. two moods, both valid. ๐Ÿ’œ

it does this by tieing the array to its internal class Module::Generic::Array::Tie that will call the add or remove callback when data is being added or removed, no matter how, i.e. be it through the methods of this class, or by directly trying to add data to it:

    use Scalar::Util qw( blessed );
    my $a = Module::Generic::Array->new();
    $a->callback( add => sub
    {
        my $def = shift( @_ );
        my( $pos, $ref ) = @$def{qw( start added )};
        return unless( blessed( $ref->[0] ) && $ref->[0]->isa( 'MyPackage') );
        return(1);
    });
    $a->push( $some_object );
    # or
    push( @$a, $some_object );

in both cases above the object from class MyPackage will be added, and if it were some other data, i.e. not from the class MyPackage, the data would not be added to the array. gatekeeping, but make it perl. ๐Ÿ’€

Like, the callback has to return true for the data to actually get added โ€” or undef to refuse it. And no, returning an empty string or 0 will not count as a rejection even though it's technically falsey. Say it with me: undef means no. ๐Ÿ’…

Both the add and remove callbacks get a hash reference as their one and only argument โ€” and that same hash ref is also sitting there as $_ inside your callback, iykyk.

The add callback receives a hash reference with these properties:

  • added โ€” an array reference of the values being added, so you can peek at them. Also available under the data property.
  • caller โ€” an array reference of the values returned by caller in perlfunc, showing where this callback was originally triggered.
  • data โ€” an array reference of the values being added, so you can inspect them. Also available under the aded property.
  • start โ€” the offset position (starting from 0).
  • type โ€” the callback type: add.

The remove callback works exactly the same way, but for any operation trying to take data out of the array. It gets a hash reference with:

  • caller โ€” an array reference of the values returned by caller in perlfunc, showing where this callback was originally triggered.
  • data โ€” an array reference of the values being removed. Also available under the removed property.
  • end โ€” the end position (starting from 0).
  • removed โ€” an array reference of the values being removed. Also available under the data property.
  • start โ€” the start position.
  • type โ€” the callback type: remove.
my $a = Module::Generic::Array->new();
$a->callback( remove => sub
{
    my $def = shift( @_ );
    my( $start, $end ) = @$def{qw( start end )};
    printf( STDERR "Called from package %s at line %d\n", @{$def->{caller}}[0,2] );
    # Do some check to accept or reject
    return(1); # always return true to accept
});
$a->splice( 3, 4 ); # Removing 4 elements starting from the position 3

That example up there would call the callback with 3 and 7, since 7 is the last position in the range of data being removed. math is mathing โœจ

my $removed = $a->shift;

Here, the arguments the callback receives would be 0 and 0. aww, they match ๐Ÿซถ

Wanna replace a callback? Just add another one โ€” it'll take the previous one's spot, no drama. ๐Ÿ’…

You can grab the callback code for a given type by calling callback with a single argument โ€” the callback type:

my $code_ref = $a->callback( 'add' );

And to yeet a callback entirely, pass undef:

$a->callback( add => undef );
$a->callback( remove => undef );

By default, an array object is not tied to Module::Generic::Array::Tie and no callbacks are set nor used. Be mindful when using callbacks, since it'll slow things down a little bit โ€” even though it's a very thin layer.

See perltie for more info on tieing data. ๐ŸŽ€


chomp ๐Ÿ“

So, picture a file whose lines were read onto an array, and each one is terminated by \n. The following removes each line's new line characters:

my $lines = Module::Generic::Array->new( \@lines );
$lines->chomp;
# Now @lines does not contain any \n at the end

newlines? never heard of her ๐Ÿ’€

clone ๐Ÿงš

Creates a clone of the current array object and returns it.

Note that this does not clone any element contained inside the array โ€” it only clones the array object itself. shallow, but make it fashion โœจ

concat ๐ŸŒˆ

This one merges two or more arrays. It does not change the existing arrays โ€” instead it returns a brand new array object. no touching the originals, bestie ๐Ÿซถ

For example:

my $array1 = Module::Generic::Array->new([qw( a b c )]);
my $array2 = [qw( d e f )];
my $array3 = $array1->concat( $array2 );

say @$array3;
# a, b, c, d, e, f

contains ๐Ÿ”

This is a convenient alias for exists. same energy, shorter name ๐Ÿ’…

delete โœ‚๏ธ

Give it an offset value and an optional length, and it removes data from the array at that offset for that length.

If you don't give it a length, it removes all entries from the offset until the end. zero chill, it just goes ๐Ÿ”ฅ

It returns a list of the removed elements in list context, or a new array object of them in scalar context.

See also splice.

each ๐Ÿ”

Pass it a code reference (like a reference to a subroutine), and it'll run that code for each element, passing the array offset and the current value as the 2 arguments. The current value is also available as $_.

$a->each(sub
{
    print( "I got $_\n" );
    # could also write:
    # print( "I got $_[1] at offset $_[0]\n" );
});

To exit the loop, return break, like this:

$a->each(sub
{
    return( $a->break ) if( $_ eq $not_this_one );
    print( "ok, this one\n" );
});

Or you could also return a non-empty false value such as 0. the more you know โญ

eighth ๐ŸŽ€

Returns the corresponding value at offset position 7 in the array by calling get_null.

If the caller expects an object back (like when you're chaining methods) and the value is defined and not a reference of any sort except scalar โ€” meaning a regular string, a scalar reference, or a scalar object โ€” it's returned as a Module::Generic::Scalar object. glow-up into an object, slay โœจ

If the value is not defined, or has zero length, it's returned as a Module::Generic::Null in object context, essentially to prevent the perl error "method called on undefined value" โ€” but at the end of the method call chain, it'll return undef. Under any other context, the value is returned as-is.

empty ๐Ÿซง

This is just an intuitive alias for reset. brain empty, no thoughts, just alias ๐Ÿ’€

error ๐Ÿ˜ญ

Returns the value of the global variable $ERROR. However, since this package doesn't set any error, you don't actually need to call it โ€” it exists nonetheless for conformity with the other packages of this distribution. iconic for showing up to a job it doesn't have ๐Ÿซถ

except ๐Ÿ™…โ€โ™€๏ธ

Give it an array reference or an array object, and it returns a new array object containing all the items that are not in the current array object. the "you're not on the list" of methods ๐Ÿ’…

For example:

my $a = Module::Generic::Array->new( [qw( Jack John Paul Peter )] );
my $other = Module::Generic::Array->new( [qw( Emmanuel Gabriel Paul Peter Raphael )] );
my $b = $a->except( $other );
# $b now contains: Jack John

exists โœ…

Give it a value โ€” references included โ€” and this returns the number of matches as a Module::Generic::Number object if it's found in the array, or false otherwise. counted, not just vibes โœจ

even ๐Ÿชž

Returns a new Module::Generic::Array object of the elements whose position in the array is an even number, starting from 0.

For example:

my $a = Module::Generic::Array->new( [qw( 1 2 3 4 5 6 7 8 9 10 )] ); my $even = $a->even; say "@$even";

Produces: 1 3 5 7 9

See also odd. balance, bestie โš–๏ธ

filter ๐Ÿงผ

This filters the array and returns a new array object. it's giving curation ๐Ÿ‘‘

As parameters it takes a code reference โ€” called for each element in the array โ€” and an optional value (typically an object). That code reference gets passed 3 arguments:

  1. the current element, which is also available as $_
  2. the element's zero-based index position
  3. the array object itself

But if an optional value was supplied, that's passed to the callback as its first parameter instead.

The code reference can return a true value to have the element added to the resulting array object, or a false value to have it ignored.

For example:

my $a = Module::Generic::Array->new( [qw( John Jack Peter Gabriel Samuel )] );
my $new = $a->filter(sub{ substr( $_, 0, 1 ) ne 'J' });
# $new now contains only Peter Gabriel Samuel

Or, passing an optional value:

my $new = $a->filter(sub
{
    my $self = shift( @_ );
    # Do something more with $self
    # Then return true or false
    substr( $_, 0, 1 ) ne 'J';
}, $self );

See also map. filtered and fabulous ๐Ÿ’–

fifth ๐Ÿ–๏ธ

Returns the corresponding value at offset position 4 in the array by calling get_null.

If the caller expects an object back (again, chaining girlies) and the value is defined and not a reference of any sort except scalar โ€” a regular string, a scalar reference, or a scalar object โ€” it comes back as a Module::Generic::Scalar object.

If the value is not defined, or has zero length, it's returned as a Module::Generic::Null in object context, essentially to prevent the perl error "method called on undefined value" โ€” but at the end of the method call chain it'll return undef. Under other context, the value is returned as-is.

first ๐Ÿฅ‡

Returns the first element of the array, if there is one. main character energy, obviously ๐Ÿ‘‘

If there are none and this method is called in an object context, it'll return a Module::Generic::Null object so chaining keeps working. Otherwise, it just returns the first element of the array, whatever that is.

For example:

# Getting the last_name property from a Person object stored in an array
$a->first->last_name;

Even if there's no such Person object, first will return a Module::Generic::Null object so the call to last_name doesn't end up as a perl exception. no crash, just vibes โœจ

But:

my $person = $a->first;

will return whatever is in the first position of the array in non-object context โ€” and in object context, if the value isn't a reference of any sort, a Module::Generic::Scalar object representing that value. For example:

my $a = Module::Generic::Array->new( [qw( Hello world )] );
say $a->first->length; # 5
# but
say $a->first; # returns "Hello" as a regular string

for ๐Ÿ”‚

Give it a subroutine reference and it'll call that sub, passing it the offset number and the corresponding array value.

$ar->for(sub
{
    my( $i, $val ) = @_;
    # do something
})

$_ is made available and contains the value of $val. convenient? we love to see it ๐Ÿ’…

It returns the object itself, so you can chain this.

To exit the loop, call break or return a defined-but-false value such as 0 or an empty string. You can even return whatever break gives you back โ€” for example:

$a->for(sub
{
    # exit now
    return( $a->break ) if( $_ eq $not_this_one );
    print( "ok, this one\n" );
});

Or you can use return:

$a->for(sub
{
    if( $_ eq $not_this_one )
    {
        $a->return( $a->break );
    }
    else
    {
        print( "ok, this one\n" );
    }
});
Okay, history lesson time, bestie: in versions on or anterior to v1.5.4 you could exit the loop by just returning undef. But since there are unfortunate opportunities for an implicit undef to be returned, that led to some issues โ€” and now it's required to return false, but defined and not empty, such as 0. no cap, respect the contract ๐Ÿซถ

So if you wanted to affect the current offset position relative to the current counter value, you can return a scalar reference containing an integer. For example:

my $a = Module::Generic::Array->new( [qw( Jack John Peter Peter Gabriel Raphael Emmanuel )] );

$a->for(sub
{
    my( $i, $name ) = @_;
    if( $name eq 'Peter' )
    {
        $a->splice( $i, 1 );
        return( \-1 );
    }
    # return true
    return(1);
});
say "@$a"; # Jack John Gabriel Raphael Emmanuel

And if you wanted to modify the counter value itself, you can change the value of the first argument provided. For example:

$a->for(sub
{
    my( $i, $name ) = @_;
    if( $name eq 'Peter' )
    {
        $a->splice( $i, 1 );
        $_[0]--;
    }
    # return true
    return(1);
});
say "@$a"; # Jack John Gabriel Raphael Emmanuel

This is useful if you want to modify the array and avoid getting unexpected results.

๐ŸŒธ foreach ๐ŸŒธ

Provided with a subroutine reference and this will call the subroutine reference, passing it the value for each entry in the array.

$ar->foreach(sub
{
    my $val = shift( @_ );
    # do something
})

It returns the object itself so this can be chained.

P.S. bestie: do not use splice while using foreach. Perl warns you against it in perlsync (https://metacpan.org/pod/perlsyn#Foreach-Loops): "foreach will get very confused if you add or remove elements within the loop body, for example with "splice". So don't do that."

Instead use for. See the example provided there on how to do it.

$_ is made available and contains the value of $val.

To exit the loop, call break or return a defined non-empty, but false value such as 0. You can even return the value returned by calling break. For example:

$a->foreach(sub
{
    # Exit the loop immediately
    return( $a->break ) if( $_ eq $not_this_one );
    print( "ok, this one\n" );
});

In version on or anterior to v1.5.4 you could exit the loop by just returning undef, but since there are unfortunate opportunities for implicit undef being returned, this led to some issues and now it is required to return false, but defined and non-empty such as 0. An empty string would not work.

๐ŸŽ€ fourth ๐ŸŽ€

Returns the corresponding value at the offset position 3 in the array by calling get_null.

If the caller expects an object in return, such as when chaining methods, and if the value is defined and not a reference of any sort (except scalar), i.e. a regular string, a scalar reference or a scalar object, it is returned as a Module::Generic::Scalar object.

If the value is not defined, or has a zero-length, it is returned as a Module::Generic::Null in object context essentially to prevent the Perl error of "method called on undefined value", but at the end of the method call chain, will return undef. Under other context, the value is returned as-is.

โœจ get โœจ

Provided an integer representing an offset and this returns the corresponding value in the array. Offsets start from 0. A blank value will be treated as 0.

my $a = Module::Generic::Array->new( [qw( abc def ghi )] );
$a->get( 1 ); # def
$a->get( '' ); # abc
$a->get( undef() ); # abc
$a->get( -1 ); # ghi

In non-object context, will return the value as is, and in object context and if the value is not a reference of any sort, it returns a Module::Generic::Scalar object representing that value. For example:

my $a = Module::Generic::Array->new( [qw( Hello world )] );
say $a->get(0)->length; # 5
# but
say $a->get(0); # returns "Hello" as a regular string
say $a->get(2); # returns undef
say $a->get(2)->length;
# object context, an Module::Generic::Scalar object is returned
# here 0 would be returned
say $a->get(2)->defined; # false

See also index.

๐Ÿฆ‹ get_callback ๐Ÿฆ‹

my $code = $a->get_callback( 'add' );
my $code = $a->get_callback( 'remove' );

Retrieve the current callback set for the specified callback type, and return the associated code reference. Only add and remove are allowed.

If there is no callback currently set, this will return undef. If you just want to check if the array has a callback, consider using has_callback instead.

๐Ÿ’œ get_null ๐Ÿ’œ

This operates the same way as get, except that if the value at the offset given is undef in perlfunc, then, instead of returning a Module::Generic::Scalar object representing that value, it will return instead a Module::Generic::Null object.

This works better if you intend to store some objects in the array, and undef went in instead, but you chain the calls expecting a method of that object to return a value. If a Module::Generic::Scalar object were returned, you would end up with an undesirable result. With a Module::Generic::Null object, it will silently accept any chaining methods you pass (it uses AUTOLOAD to do that) and ultimately (when you are out of object context) return undef.

my $a = Module::Generic::Array->new( [qw( Hello world )] );
say $a->get(2)->length; # undef
say $a->get(2)->whatever; # undef
say $a->ge(2)->method1->method2->name; # undef
say $a->get(2); # undef

๐Ÿ“ grep ๐Ÿ“

# returns a regular list
my( @list ) = $a->grep( 'something' );
my( @list ) = $a->grep( qr/something/ );
my( @list ) = $a->grep(sub
{
    /^something$/i;
});
# returns an array object in scalar context
my $list = $a->grep( 'something' );
my $list = $a->grep( qr/something/ );
my $list = $a->grep(sub
{
    /^something$/i;
});
# or
my $list = $a->grep(sub
{
    my( $val, $index ) = @_;
    $val =~ /^something$/i && $index > 2;
});
# get all the elements NOT matching
my $list = $a->grep( 'something', 0 );
my $list = $a->grep( qr/something/, 0 );
my $list = $a->grep(sub
{
    /^something$/i;
}, 0);

Provided with some data, and this will do a grep on the array.

If the data provided is a code reference or a reference to a subroutine, the code reference will be called for each array entry, and $_ will also be available for each entry. The code reference is passed 2 arguments:

  1. The current value of the array
  2. The index in the array (starting from 0)

If the data is a regular expression, each array entry is tested against it.

It takes an optional boolean value, and if false (default), it returns all the entries matching, and if true, it returns all the entries not matching.

It returns a list of matches found in list context and a new Module::Generic::Array in scalar context.

๐Ÿซถ has ๐Ÿซถ

This is an alias for exists.

๐ŸŒˆ has_callback ๐ŸŒˆ

$a->has_callback( 'add' );
$a->has_callback( 'remove' );

Or, if you just want to check if there is any callback set:

$a->has_callback;

Checks if the array object has a callback for the specified type, and returns true or false. Only add or remove is supported.

If no callback type is specified, this will check if any callback has been set for this array object.

โญ index โญ

Provided with an index of an element in the array and this returns its corresponding value as is in non-object context, and in object context and if the value is not a reference of any sort, it returns a Module::Generic::Scalar object.

It takes an integer and this ensures the value used is an integer by applying int in perlfunc.

my $a = Module::Generic::Array->new( [qw( John Jack Peter )] );
$a->index( 1 ); # returns Jack

And in object context:

say $a->index( 1 )->substr( 0, 2 ); # returns "Ja"

If there is nothing at the given offset, possibly because the array is smaller, then this would return undef in non-object context, or in object context, a Module::Generic::Scalar object representing undef().

๐Ÿงš intersection ๐Ÿงš

Provided with an array object, an array reference or a list of elements and this will return a new array object containing all the common elements in both the current array object and the provided list or array reference.

my $intersec1 = [qw( Jack John Paul Peter )];
my $intersec2 = [qw( Emmanuel Gabriel Raphael Peter Michel )];
my $intersec = Module::Generic::Array->new( $intersec1 )->intersection( $intersec2 );
# $intersec now contains 'Peter'

This method basically creates a hash of the current array object and then using grep on the newly provided data, checks if any entry exists in the hash and returns the result as a new object.

๐Ÿฆ‹ iterator ๐Ÿฆ‹

This returns a new iterator to cycle through all the array items using iterator's method, such as next in Module::Generic::Iterator and prev in Module::Generic::Iterator. Each iterator element is an Module::Generic::Iterator::Element object.

my $i = $a->iterator;
while( $i->has_next )
{
    my $elem = $i->next;
    my $value = $elem->value;
    # Get the next element relative to our element
    printf( "Next value is: %s at offset %d\n", $elem->next, $elem->next->pos  );
}

๐ŸŽ€ is_empty ๐ŸŽ€

Returns true if the array is empty, false otherwise.

๐Ÿ’– join ๐Ÿ’–

Provided with a string, or expression just as documented in join in perlfunc and this will return a string as an Module::Generic::Scalar object.

๐Ÿ“ keys ๐Ÿ“

my $ar = Module::Generic::Array->new( [qw( Joe John Mary )] );
print $ar->keys->as_string, "\n"; # 0 1 2

This works as documented in keys in perlfunc and returns a new Module::Generic::Array object of offset values for each entry in the array.

๐Ÿ‘‘ last ๐Ÿ‘‘

Returns the last element of the array, whatever that is, in non-object context, and in object context and if the value is not a reference of any sort, it returns a Module::Generic::Scalar object representing that value. If there are none, instead it will return a Module::Generic::Null to ensure chaining will still work.

For example:

my $a = Module::Generic::Array->new( [qw( Hello world )] );
say $a->last->length; # 5
# but
say $a->last; # returns "world" as a regular string

โœจ length โœจ

Returns the size of the array, starting from 1, as a Module::Generic::Number object.

This is different from size that returns value from 0 and -1 if the array is empty.

๐ŸŒˆ list ๐ŸŒˆ

Returns the array as a list.

my $a = Module::Generic::Array->new( [qw( Joe John Mary )] );
print( "@$a" ); # Joe John Mary
my @people = $a->list; # @people now is ( "Joe", "John", "Mary" )

๐Ÿ—บ๏ธ map

okay so you hand this method a reference to a subroutine, and it calls that sub for every single element of the array. In list context it gives you back a list; otherwise it returns a brand-new Module::Generic::Array. Bestie, itโ€™s giving โ€œdo a little thing to each itemโ€ energy โœจ

For every iteration, $_ is available. Iconic.

print( $a->map(sub{ $_->value })->join( "\n" ), "\n" );

If you want map to discard a value, your anonymous subroutine has to return an empty list, like this:

my $a = Module::Generic::Array->new( [qw( Joe John Mary )] );
my $new = $a->map(sub
{
    return if( $_ eq 'John' );
    return( $_ );
});

$new will be a Module::Generic::Array object containing only Joe and Mary. slay ๐Ÿ’…

But do not return undef explicitly in your anonymous subroutine, because perlโ€™s map expects an empty list to discard the entry, and undef is not an empty list. So this next one is wrong:

my $a = Module::Generic::Array->new( [qw( Joe John Mary )] );
my $new = $a->map(sub
{
    return( undef ) if( $_ eq 'John' );
    return( $_ );
});

See also filter ๐Ÿซถ


๐Ÿฆ‹ max

Returns the element in the array object that has the highest numerical value, as a Module::Generic::Scalar object. No cap, it just finds the biggest vibe ๐Ÿ”ฅ

my $values = Module::Generic::Array->new( [qw( 9 5 12 3 7 )] );
my $max = $values->max;
# $max is 12

If the array object is empty, it returns a Module::Generic::Scalar object representing undef. Yes, even the empty case gets a whole object, because weโ€™re extra like that ๐Ÿ’€

my $list = Module::Generic::Array->new;
my $max  = $list->max; # $max is undef
$max->defined: # returns false

This method is a wrapper around max in List::Util ๐ŸŒธ


๐ŸŽ€ merge

Provided with a list of Module::Generic::Array objects, and this method merges them with our current one โ€” i.e. the array object you used to call merge in the first place. Group project but make it arrays ๐Ÿ’–

For example:

my $a = Module::Generic::Array->new( [qw( Jack John Peter )] );
my $b = Module::Generic::Array->new( [qw( Gabriel Raphael Emmanuel )] );
$a->merge( $b );
print( $a->join( ' ' ), "\n" ); # Jack John Peter Gabriel Raphael Emmanuel

Alternatively, you could simply do:

$a->push( $b->list );

Note that this will not discard duplicates, if any. If you want to remove possible duplicates, you could do:

$a->merge( $b )->unique;

periodt ๐Ÿงš


๐Ÿš min

Same as max, but returns the element in the array object that has the lowest numerical value, as a Module::Generic::Scalar object. Tiny value supremacy ๐ŸŒˆ

my $values = Module::Generic::Array->new( [qw( 9 5 12 3 7 )] );
my $min = $values->max;
# $min is 3
bestie the code block literally says ->max but the comment promises $min is 3 โ€” Iโ€™m just the messenger, copy/paste with care ๐Ÿ˜ญ

9๏ธโƒฃ ninth

Returns the corresponding value at the offset position 8 in the array by calling get_null. Yes, position 8. Not 9. Donโ€™t ask, itโ€™s just built like that ๐Ÿ’…

If the caller expects an object in return โ€” like when youโ€™re chaining methods โ€” and if the value is defined and not a reference of any sort (except scalar), i.e. a regular string, a scalar reference or a scalar object, it is returned as a Module::Generic::Scalar object.

If the value is not defined, or has a zero-length, it is returned as a Module::Generic::Null in object context essentially to prevent perl error of โ€œmethod called on undefined valueโ€, but at the end of the method call chain, will return undef. Under other context, the value is returned as-is. fr fr ๐Ÿซถ


๐Ÿ‘‘ object

Returns the current object. This is useful when chaining to force an object context. Main character energy: it just hands you back yourself ๐Ÿ˜Œโœจ


๐Ÿฆ‹ odd

Returns a new Module::Generic::Array object of elements whose position in the array are an odd number, starting from 0.

For example:

my $a = Module::Generic::Array->new( [qw( 1 2 3 4 5 6 7 8 9 10 )] ); my
$odd = $a->odd; say "@$odd";

Produces: "2 4 6 8 10"

See also even ๐ŸŒธ


๐ŸŽ€ offset

This takes 2 integers as arguments: an offset and optionally a length, and it will return a Module::Generic::Array object representing this segment from the current array. Offset starts at 0.

For example:

my $a = $m->new_array( [qw( Jack John Peter Gabriel Raphael Emmanuel )] );
print( $a->offset( 2, 3 )->join( ' ' ), "\n" ); # John Peter Gabriel

Note that the arguments are converted into an integer, so if you provide a non-integer value, it will be turned into one. In this regard, undef would turn into zero.

print( $a->offset( 2, undef )->join( ' ' ), "\n" ); # returns nothing, because length (undef) became 0

If you provide a negative length, it will start back by that much from the offset point up to the offset point.

print( $a->offset( 2, -1 )->join( ' ' ), "\n" ); # John Peter

And if the length is negative, it will start back from the end of the array:

print( $a->offset( 2, -3 )->join( ' ' ), "\n" ); # Emmanuel Jack John Peter

The offset itself can be negative and it will position it starting from the end of the array:

print( $a->offset( -2, 3 )->join( ' ' ), "\n" ); # Raphael Emmanuel Jack

If only an offset position is provided and no length, it will return all elements from that position until the end of the array:

print( $a->offset(3)->join( ' ' ), "\n" ); # Gabriel Raphael Emmanuel

See splice especially if you want to remove segments of elements from the current array, such as:

print( $a->splice( 1 ) ); # removes and returns John Peter Gabriel Raphael Emmanuel

See get or index if you want to return only one element at a certain offset position. iykyk ๐Ÿ’–


๐Ÿ“ฆ pack

my $a = Module::Generic::Array->new( 30..39 );
my $s = $a->pack( 'H2' x 10 );

Like pack in perlfunc, this takes a template and converts the array object. โ€œThe resulting string is the concatenation of the converted values.โ€

It returns a new Module::Generic::Scalar object.

See also pack in Module::Generic::Scalar โœจ


๐Ÿ“ pop

In non-object context, it returns the last entry in the array, whatever that is. In object context, and if the value is not a reference of any sort, this returns a Module::Generic::Scalar object.

For example:

my $a = Module::Generic::Array->new( [qw( Hello world )] );
say $a->pop->length; # 5
# but
say $a->pop; # returns "world" as a regular string

okay but the way object context changes the whole outfit ๐Ÿ˜ญ๐Ÿ’…


๐Ÿ”Ž pos

Provided with some value (references are okay too), and this will return the position (starting from 0) of it in the array, or undef if nothing was found.

my $a = Module::Generic::Array->new( [qw( John Jack Peter )] );
my $offset = $a->pos( 'Jack' ); # returns 1
$a->pos( 'Bob' ); # Returns undef
my $hash = { first_name => 'John', last_name => 'Doe' };
$a->push( $hash );
$a->pos( $hash ); # Returns 3

Note that it returns the position in the array of the first occurrence found. Maybe I should consider returning a list of all occurrences in list context? ๐Ÿ‘€


๐ŸŒธ prepend

This is an alias for unshift. Cute little name change, same energy ๐ŸŽ€


๐Ÿซถ push

Provided with some data, and this adds it at the end of the array.

Note that pushing a Module::Generic::Array object into another Module::Generic::Array object does not actually expand it, because this would imply making an assumption on what the user actually wants. Thus, you would need to make that clear yourself.

my $a = Module::Generic::Array->new( [qw( John Jack Peter )] );
my $b = Module::Generic::Array->new( [qw( Gabriel Raphael Emmanuel )] );
$a->push( $b );
# Now $a contains something like: John Jack Peter Module::Generic::Array=ARRAY(0x557d2c2983e8)

Instead you might want to do:

$a->push( $b->list );

Or if you prefer:

$a->merge( $b ); # $a now is: John Jack Peter Gabriel Raphael Emmanuel

which will merge array object $b into $a, by pushing all of $bโ€™s elements at the end of $aโ€™s stack. no cap, thatโ€™s the whole plot ๐Ÿ”ฅ


๐Ÿงบ push_arrayref

Provided with an array reference, and this adds all its entries at the end of the array.

my $ar = Module::Generic::Array->new( [qw( John Joe Mary )]);
$ar->push_arrayref( [qw( Jack Peter )] );
print( $ar->join( "," ), "\n" );
# Now prints: John, Joe, Mary, Jack, Peter

slay, whole array ref just got folded in ๐Ÿ’–


๐ŸŒˆ reduce

my $final_value = $array->reduce(sub{ $_[0] + $_[1] });
# or, with an optional initial value
my $final_value = $array->reduce(sub{ $_[0] + $_[1] }, 10);

This is an implementation of the JavaScript reduce equivalent. In that, it is different from the reduce implementation in List::Util that departed from the original JavaScript alter ego.

This method takes a subroutine reference, or an anonymous subroutine, as its first parameter, and an optional initial value as its second parameter.

If an initial value was provided, the โ€œaccumulatorโ€ value will be set to that initial value and reduce will start iterating from offset 0. Otherwise, the โ€œaccumulatorโ€ value will be set to the first array value, and the iteration will start from offset 1.

For each iteration, it will call the callback, in scalar context, with 3 arguments:

  1. the current value of the โ€œaccumulatorโ€
  2. the value at the current offset
  3. the value of the current offset

And $_ will be set to the value of the array object at the current position.

The โ€œaccumulatorโ€ value gets updated by the return value of each invocation of the callback.

It returns the resulting value of the โ€œaccumulatorโ€.

For example:

my $array = Module::Generic::Array->new(0, 1, 2, 3, 4);
my $rv = $array->reduce(sub
{
    my( $accumulator, $current_value, $offset ) = @_;
    # $current_value is also accessible as $_
    return( $accumulator + $current_value );
});

The return value in the above example would be 10.

Since reduce will not skip array indexes that have an undefined value, you need to be mindful of the definedness of the current value passed, and also that of the โ€œaccumulatorโ€.

my $array = Module::Generic::Array->new;
$array->[0] = 0;
$array->[2] = 1;
$array->[4] = 2;
$array->[6] = 3;
$array->[8] = 4;

As you see, we assigned values in the array object at every other slot, and yet, if we do:

my $rv = $array->reduce(sub
{
    my( $accumulator, $current_value, $offset ) = @_;
    return( $accumulator ) if( !defined( $current_value ) );
    # do something
    return( $something_else );
});

If you decided to mutate the โ€œaccumulatorโ€ instead of copying it, remember to still return, in the callback, its modified value, or the next iteration will receive whatever was the last value of your callback, which might be undef.

For example:

my $rv = $array->reduce(sub
{
    $_[0] += $_[1];
    return( $_[0] );
});

Any change, within the callback, to the array object structure, or array values, is not recommended as it would lead to unpredictable results and poor code readability โ€” just like it would if you did that while using foreach. Bestie, do not do chaotic things mid-iteration, Iโ€™m begging ๐Ÿ˜ญ๐Ÿซถ

Edge cases:

okay so bestie, letโ€™s finish the reduce lore โ˜•โœจ: if the array has exactly one element โ€” doesnโ€™t matter where it sits โ€” and no initial value is provided, or if an initial value is provided but the array is empty, that solo value gets returned and the callback is not called. no callback, no drama.

if an initial value is provided and the array is not empty, reduce will always invoke the callback starting at offset 0.

if no initial value is provided, reduce behaves differently for arrays with length larger than 1, equal to 1, and 0. like, watch:

use POSIX;
my $getMax = sub
{
    my( $a, $b ) = @_;
    return( POSIX::fmax( $a, $b ) );
};

# callback is invoked for each element in the array starting at offset 0
Module::Generic::Array->new([1, 100])->reduce( $getMax, 50 ); # 100
Module::Generic::Array->new([50])->reduce( $getMax, 10 ); # 50

# callback is invoked once for element at offset 1
Module::Generic::Array->new([1, 100])->reduce( $getMax ); # 100

# callback is not invoked
Module::Generic::Array->new([50])->reduce( $getMax ); # 50
Module::Generic::Array->new([])->reduce( $getMax, 1 ); # 1

Module::Generic::Array->new([])->reduce( $getMax ); # Error, returns undef, or an empty list in list context

any fatal error that happens in the callback gets caught, an error object gets set, and you get undef back in scalar context โ€” or an empty list in list context. ๐Ÿ’€

peep the Mozilla documentation at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce.

remove ๐Ÿงน

this takes a Module::Generic::Array object, or an array reference, or a regular array (i.e. a list) of elements and removes them from the current array object. it works on references too. ๐Ÿซถ

my $dummy = { class => 'Hello' };
my $a = Module::Generic::Array->new( ['Jack', 'John', $dummy, 'Paul', 'Peter', 'Gabriel', 'Raphael', 'Emmanuel'] );
$a->remove( $dummy, qw( John Paul Peter Emmanuel ) );
say( "@$a" ); # Jack Gabriel Raphael

it returns the current object. ๐Ÿ’…

replace ๐Ÿ”

give it an old entry and a new one, and itโ€™ll try to find the index position of the old entry. if it finds it, boom ๐Ÿ’ฅ it replaces it with the new one.

reset ๐Ÿงผ

this empties the array, just like undef.

return ๐Ÿ›‘

this method is used to send the calling array a return value. it works across multiple embedded loops. for example:

telling the loop for array $a to terminate while we are in loop for array $b:

$a->for(sub
{
    my( $i, $n ) = @_;
    $pos = $n;
    $b->for(sub
    {
        my( $j, $v ) = @_;
        # Tell loop for array $a to stop
        $a->return( undef() ) if( $n == 7 && $v == 27 );
    });
    # some more stuff here....
});

telling the loop for array $a to skip 1:

my $a = Module::Generic::Array->new( [qw( Jack John Peter Paul Gabriel Raphael Emmanuel )] );
$a->for(sub
{
    my( $i, $n ) = @_;
    # tell it to skip Peter
    $a->return( +1 ) if( $n eq 'John' );
    return( 1 );
});

it works by having the loop for the given array check for a return value assigned to it at each iteration. because it is just a check in a hash, itโ€™s very lightweight. when a return value is found, it gets reset immediately. โœจ

return_reset ๐Ÿ”„

resets the return value used in methods that implement loop functions. thatโ€™s it, thatโ€™s the method. ๐Ÿ’…

reverse ๐Ÿ”ƒ

returns the array in reverse order โ€” as a plain list in list context, or as a new Module::Generic::Array object in scalar context. ๐Ÿฆ‹

scalar ๐Ÿงฎ

returns the size of the array. it basically calls length.

second ๐Ÿฅˆ

returns the corresponding value at the offset position 1 in the array by calling get_null. ๐ŸŽ€

if the caller expects an object back โ€” like when youโ€™re chaining methods โ€” and the value is defined and isnโ€™t a reference of any sort (except scalar), i.e. a regular string, a scalar reference, or a scalar object, it gets returned as a Module::Generic::Scalar object.

if the value is not defined, or has a zero-length, it comes back as a Module::Generic::Null in object context โ€” essentially so perl doesnโ€™t throw the method called on undefined value error. but at the end of the method call chain, it will return undef. under other context, the value is returned as-is. ๐Ÿ˜Œ

set ๐Ÿงบ

provide it with an array, an array reference, or an array-based object, and it replaces all the data in the current object with the ones you provided. ๐Ÿ’–

note that if an array object is provided, it will copy the content of that object and not set the array object itself. important distinction, bestie.

$a->set( qw( John Jack Peter ) ); # Using an array of elements
$a->set( [qw( John Jack Peter )] ); # Using an array reference of elements
$a->set( $a2 ); # Using another array object, whatever its class may be

seventh ๐ŸŒˆ

returns the corresponding value at the offset position 6 in the array by calling get_null. ๐Ÿฆ‹

same object-context rules as always: if the caller wants an object (chaining vibes), and the value is defined and not any kind of reference except scalar โ€” so a regular string, a scalar reference, or a scalar object โ€” you get a Module::Generic::Scalar object.

if itโ€™s not defined or has a zero-length, object context gives you a Module::Generic::Null so perl doesnโ€™t hit you with method called on undefined value. at the end of the chain, though, it returns undef. any other context just returns the value as-is. โœจ

shift โฌ…๏ธ

removes the first entry and returns it as is. in non-object context, it removes the first entry in the array and returns it, whatever that is. in object context and if the value is not a reference of any sort, this returns a Module::Generic::Scalar object. ๐Ÿ’…

for example:

my $a = Module::Generic::Array->new( [qw( Hello world )] );
say $a->shift->length; # 5
# but
say $a->shift; # returns "Hello" as a regular string

sixth ๐ŸŽฒ

returns the corresponding value at the offset position 5 in the array by calling get_null. ๐ŸŒธ

if the caller expects an object back, like when chaining methods, and the value is defined and not a reference of any sort (except scalar), i.e. a regular string, a scalar reference, or a scalar object, it is returned as a Module::Generic::Scalar object.

if the value is not defined, or has a zero-length, it is returned as a Module::Generic::Null in object context โ€” essentially to prevent the perl error method called on undefined value โ€” but at the end of the method call chain, it will return undef. under other context, the value is returned as-is. ๐Ÿ˜ญ

size ๐Ÿ”ข

returns the size of the array starting from 0, and -1 if the array is empty, as a Module::Generic::Number object. ๐Ÿงฎ

this is equivalent to the perl variable $# as documented in perldata. it returns the last index in the array.

this is different from length that returns value from 1 and 0 if the array is empty.

sort ๐Ÿ”ค

sorts the array and returns the new array as a list in list context or a new Module::Generic::Array object in scalar context. โœจ

it takes an anonymous subroutine or a code reference as an optional argument, and if provided, it will be used to sort the data. see sort in perlfunc for more information. this sub gets passed the two elements $a and $b and must return less than, equal to, or greater than 0.

my $new_object = $array->sort;
my @list = $array->sort;
my $new_object = $array->sort(sub{ $_[0] <=> $_[1] });

splice โœ‚๏ธ

takes the same arguments as the splice in perlfunc function, but its return value is different.

if splice is called to add a new element, the array object is returned to allow chaining.

if no argument is provided, it just empties the array and the array object is returned to allow chaining.

when only an offset and/or length are provided, it returns the list of elements found as a regular list (not an object) in non-object context. however, in object context, this returns a new Module::Generic::Array object. ๐Ÿฆ‹

for example:

my $a = Module::Generic::Array->new( [qw( I disapprove of what you say, but I will defend to the death your right to say it )] );
say $a->splice( 7, 3 ); # returns a list containing "I", "will", "defend"
say $a->splice( 7 ); # returns a list containing "I", "will", "defend", "to", "the", "death", "your", "right", "to", "say", "it"

but in object context:

say a->splice( 7, 3 )->length; # returns 3 obviously
say a->splice( 7 )->length; # returns 11

here we use the method length but any Module::Generic::Array method works. ๐Ÿ’…

split ๐ŸŒธ

just like the normal split in perlfunc function, it takes a string or expression and splits the data provided into a list of elements.

it returns the list in list context, and returns a new Module::Generic::Array object in scalar context.

it achieves this by creating a new Module::Generic::Scalar object out of the string given and then calling split in Module::Generic::Scalar.

# Using an existing array object
my $a = $ar->split( qr/[[:blank:]\h]+/, "I disapprove of what you say, but I will defend to the death your right to say it" );
$a->length; # 18
# or in list context and using the method as a class method
my @words = Module::Generic::Array->split( qr/[[:blank:]\h]+/, "I disapprove of what you say, but I will defend to the death your right to say it" );

tenth ๐Ÿ”Ÿ

returns the corresponding value at the offset position 9 in the array by calling get_null. ๐Ÿ‘‘

if the caller expects an object in return โ€” such as when chaining methods โ€” and the value is defined and not a reference of any sort (except scalar), i.e. a regular string, a scalar reference, or a scalar object, it is returned as a Module::Generic::Scalar object.

if the value is not defined, or has a zero-length, it is returned as a Module::Generic::Null in object context, essentially to prevent perlโ€™s method called on undefined value error. but at the end of the method call chain, it will return undef. under other context, the value is returned as-is. ๐Ÿ’œ

third ๐Ÿฅ‰

returns the corresponding value at the offset position 2 in the array by calling get_null. ๐ŸŽ€

if the caller expects an object back, like when chaining methods, and the value is defined and not a reference of any sort (except scalar), i.e. a regular string, a scalar reference, or a scalar object, it comes back as a Module::Generic::Scalar object.

if the value is not defined, or has a zero-length, it is returned as a Module::Generic::Null in object context โ€” essentially to prevent the perl error method called on undefined value โ€” but at the end of the method call chain, it will return undef. under other context, the value is returned as-is. ๐Ÿ˜Œ

  • unchomp โ€” okay so this is literally the opposite of chomp: it adds a newline to every entry in the array. You can set what โ€œnewlineโ€ means by giving unchomp an optional value; if you donโ€™t, it defaults to $/. It returns the current object. ๐Ÿ’…
  • undef โ€” just like reset, this empties the array. (yes bestie, itโ€™s giving โ€œclear the group chat.โ€)
  • unique โ€” uses List::Util to filter out duplicates, including reference duplicates, and returns a new Module::Generic::Array object holding the resulting array. Optionally, you can pass it a true value, and it will update the object youโ€™re already using instead.
my $dummy = { class => 'Hello' };
my $a = Module::Generic::Array->new( ['Jack', 'John', $dummy, 'Paul', 'Peter', 'Gabriel', $dummy, 'Peter', 'Raphael', 'Emmanuel'] );
my $b = $a->unique;
# $b now contains: 'Jack', 'John', $dummy, 'Paul', 'Peter', 'Gabriel', 'Raphael', 'Emmanuel'

or to update $a directly:

$a->unique(1);
  • unshift โ€” adds the given values at the beginning of the array. ๐ŸŒธ
  • values โ€” gets a list of all the array values and returns a list in list context or a ne Module::Generic::Array object in scalar context. (yes, the page says ne, bestie โ€” we keep the lore exactly as written.)

๐Ÿ’พ SERIALISATION ๐Ÿ’พ

Serialisation by CBOR, Sereal and Storable::Improved (or the legacy Storable) is supported by this package. To that effect, the following subroutines are implemented: FREEZE, THAW, STORABLE_freeze and STORABLE_thaw. ๐ŸŽ€

๐Ÿงต THREAD & PROCESS SAFETY ๐Ÿงต

This module is designed to be fully thread-safe and process-safe, ensuring data integrity across Perl ithreads and mod_perlโ€™s threaded Multi-Processing Modules (MPMs) such as Worker or Event. It relies on Module::Generic::Global for thread-safe storage of shared state and employs synchronisation mechanisms to prevent data corruption and race conditions. โœจ

๐Ÿ” Synchronisation Mechanisms ๐Ÿ”

  • Shared State โ€” the module uses Module::Generic::Global to manage shared state in three namespaces:
    • "errors" โ€” stores error objects for "error" and "pass_error", keyed by object reference address, process ID, and thread ID (if applicable).
    • "return" โ€” stores return values for "break", "return", and "return_reset", keyed similarly.
    • "loaded_classes" โ€” tracks loaded classes in "_load_class", keyed by class name and thread ID (if applicable).
    • These repositories are :shared when CAN_THREADS is true (Perl supports ithreads), protected by lock in perlfunc for Perl threads or APR::ThreadRWLock for mod_perl threaded MPMs without threads. In non-threaded environments, repositories are per-process, requiring no synchronisation.
  • Tied Arrays โ€” when callbacks are set via "callback", the array is tied to "Module::Generic::Array::Tie". As of version 2.2.2, tied array operations (e.g., "PUSH", "POP", "STORE") are thread-safe, as they rely on Module::Generic::Globalโ€™s synchronisation. However, callbacks themselves are not inherently thread-safe. If a callback accesses shared resources or performs complex operations, you must implement additional synchronisation (e.g., using lock or Thread::Semaphore). ๐Ÿซถ

๐Ÿงฌ Context Key Isolation ๐Ÿงฌ

Module::Generic::Global uses context keys to isolate data:

  • Object-Level Keys โ€” methods like "error", "break", "return", "return_reset", and "DESTROY" use object-level keys ("<refaddr>;<pid>[;<tid>]"), where "refaddr" is the objectโ€™s reference address, "pid" is the process ID, and "tid" is the thread ID (if "HAS_THREADS" is true). This ensures thread- and process-specific isolation for errors and return values.
  • Class-Level Keys โ€” "_load_class" uses class-level keys ("<class>[;<tid>]"), isolating loaded class tracking per thread or process.

Keys differ between threaded ("<refaddr>;<pid>;<tid>") and non-threaded ("<refaddr>;<pid>") environments, preventing cross-context interference. โญ

๐Ÿšจ Error Handling ๐Ÿšจ

Errors are stored in the "errors" namespace, with one error per object-process-thread combination. The package-global $ERROR is retained for backward compatibility but is not cleared in "DESTROY" to avoid affecting other objects. Errors are serialised using Storable::Improved for thread compatibility. ๐Ÿ˜ญ

๐Ÿช mod_perl Considerations ๐Ÿช

  • Prefork MPM โ€” data is per-process, requiring no additional synchronisation.
  • Threaded MPMs (Worker/Event) โ€” shared repositories are protected by Module::Generic::Globalโ€™s synchronisation. Users should call Module::Generic::Global->cleanup_register โ€” the original page renders this as "Module::Generic::Global-"cleanup_register> โ€” in mod_perl handlers to clear repositories after requests, preventing memory leaks.
  • Thread-Unsafe Functions โ€” avoid Perl functions like "localtime", "readdir", "srand", or operations like "chdir", "umask", "chroot" in threaded MPMs, as they may affect all threads. Consult perlthrtut (http://perldoc.perl.org/perlthrtut.html) and mod_perl documentation (https://perl.apache.org/docs/2.0/user/coding/coding.html#Thread_environment_Issues) for details. ๐Ÿ’€

๐Ÿ’– Recommendations for Threaded Applications ๐Ÿ’–

  • Use non-tied arrays without additional synchronisation, as Module::Generic::Global handles shared state.
  • For tied arrays, ensure callbacks are thread-safe by adding locks for shared resources.
  • In mod_perl, use "cleanup_register" to manage memory.

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

  • Module::Generic::Scalar
  • Module::Generic::Number
  • Module::Generic::Boolean
  • Module::Generic::Hash
  • Module::Generic::Dynamic

โœ๏ธ AUTHOR โœ๏ธ

Jacques Deguest <jack@deguest.jp> ๐Ÿฆ‹

Copyright (c) 2000-2024 DEGUEST Pte. Ltd.

You can use, copy, modify and redistribute this package and associated files under the same terms as Perl itself.


and thatโ€™s the whole Module:...::Array(3) page, bestie โ€” source footer vibes: perl v5.42.2, dated 2026-02-15. go slay some arrays ๐Ÿ’–โœจ

๐Ÿ“ฆ where this page comes from