Module:...ic::Hash(3)
π Module::Generic::Hash(3) π
okay bestie, this is the User Contributed Perl Documentation page for Module::Generic::Hash(3) β and it's giving βtiny hash object with main character energy.β π No cap, we're keeping every detail.
πΈ NAME πΈ
Module::Generic::Hash β Hash Manipulation Object Class π
π¦ SYNOPSIS π¦
bestie, here's the whole usage vibe board. Copy it exactly, okay? π
my $h = Module::Generic::Hash->new({
first_name => 'John',
last_name => 'Doe',
age => 30,
email => 'john.doe@example.com',
});
# or
my $h = Module::Generic::Hash->new(
first_name => 'John',
last_name => 'Doe',
age => 30,
email => 'john.doe@example.com',
);
my $keys = $h->keys # Module::Generic::Array returned
$h->keys->length # e.g. 10
$keys->pop # See Module::Generic::Array
print( $h->as_string, "\n" );
# Produces:
{
"age" => 30,
"email" => "john.doe\@example.com",
"first_name" => "John",
"last_name" => "Doe"
}
$h->json({ pretty => 1 });
# Produces
{
"age" : 30,
"email" : "john.doe@example.com",
"first_name" : "John",
"last_name" : "Doe"
}
# Or
$h->json
# Produces
{"age":30,"email":"john.doe@example.com","first_name":"John","last_name":"Doe"}
# Adding a key and value as usual:
$h->{role} = 'customer';
$h->defined( 'role' ) # True
$h->delete( 'role' ) # Removes and returns 'customer'
$h->each(sub
{
my( $k, $v ) = @_;
print( "Key $k has value '$v'\n" );
});
exists( $h->{age} );
# same as
$h->exists( 'age' );
# Same as $h->foreach(sub{ #.. });
$h->for(sub{
my( $k, $v ) = @_;
print( "Key $k has value '$v'\n" );
});
$h->length # Returns a Module::Generic::Number
my $hash2 =
{
address =>
{
line1 => '1-2-3 Kudan-minami, Chiyoda-ku',
line2 => 'Big bld 7F',
postal_code => '123-4567',
city => 'Tokyo',
country => 'jp',
},
last_name => 'Smith',
};
my $h2 = Module::Generic::Hash->new( $hash2 );
$h->merge( $hash2 );
# same as $h->merge( $h2 );
$h > $h2 # True
$h gt $h2 # True
$h >= $h2 # True
$h2 < $h # True
$h2 lt $h # True
$h2 <= $h # True
3 < $h # True
# Merge $hash2 into $h, but without overwriting existing entries
$h->merge( $hash2, { overwrite => 0 });
# Otherwise, bluntly overwriting existing entries, if any
$h->merge( $hash2 );
# Same copy
my $h3 = $h->clone;
my $vals = $h->values; # Returns a Module::Generic::Array
# Must return an empty list to prevent the entry from being added to the result, as per perlfunc documentation, see map
my $vals = $h->values(sub{
ref( $_[0] ) ? () : $_[0];
}, { sort => 1 });
# Using reference as key is ok too.
my $h = Module::Generic::Hash->new;
# Enable the use of reference or objects as hash keys
$h->key_object(1);
# or
local $Module::Generic::Hash::KEY_OBJECT = 1;
my $h = Module::Generic::Hash->new;
# Now, we can use reference or object as hash keys
my $array = [qw( John Paul Jack Peter )];
my $ref = { name => 'John Doe' };
my $code = sub{1};
my $scalar = \'Hello'
my $glob = \*main;
my $foo = Foo::Bar->new;
$h->{ $array } = 'array';
$h->{ $ref } = 'hash';
$h->{ $code } = 'code';
$h->{ $scalar } = 'scalar';
$h->{ $glob } = 'glob';
$h->{ $foo } = 'object';
π VERSION π
v1.5.1 β that's the version, bestie. β¨
π DESCRIPTION π
The whole purpose of this class/package is to give you a lightweight object-oriented approach to hash manipulation and to enable the use of any type of hash key, including regular string and reference, such as array reference, hash reference, anonymous subroutine, scalar reference, filehandle and objects. π«Ά
If you want to store keys as reference, just make sure to instantiate the object first and set the method key_object to a true value, before adding keys as reference, because perl regular hash will transform any reference into a string to be used as a key. π
Thus the following would not work as you would expect:
my $ref = {};
my $array = [qw( John Paul Jack Peter )];
$ref->{ $array } = 'my array';
local $Module::Generic::Hash::KEY_OBJECT = 1;
my $h = Module::Generic::Hash->new( $ref );
Instead, do either:
my $array = [qw( John Paul Jack Peter )];
my $h = Module::Generic::Hash->new;
$h->key_object(1);
# or
local $Module::Generic::Hash::KEY_OBJECT = 1;
my $h = Module::Generic::Hash->new;
# then
$h->{ $array } = 'my array';
or:
my $array = [qw( John Paul Jack Peter )];
local $Module::Generic::Hash::KEY_OBJECT = 1;
my $h = Module::Generic::Hash->new( $array => 'my array' );
This uses perl core functions only and Clone for cloning. This module's methods act as a wrapper to them. π
Because the object is overloaded, you can use the variable with comparison perl operators, such as :
$h > 3 # True
$h <= 3 # False
# etc...
You can also compare two hashes reliably, such as :
$h1 eq $h2 # True
But if you use ==, it will compare the hash size, i.e. the number of keys
$h1 == $h2
Which could be true if both hashes have the same number of keys (==), but may not be true if they are not the same (eq). π¦
Otherwise, the hash can be accessed like a regular hash. For example :
print( "Customer is $h->{first_name} $h->{last_name}\n" );
π METHODS π
β¨ new
Give it a hash reference, some optional parameters, and it hands you back a brand-new object. Slay.
Possible optional parameters are:
debugβ pass an integer and it activates/deactivates debugging messages. Below3, literally nothing meaningful happens, bestie.
β¨ as_hash
Returns the hash object as a regular hash reference. It copies all the keys and their values into a new anonymous hash and returns it. Cute, clean, done.
Optionally, it takes a hash or hash reference of options. If the option strict is provided with a true value, then instead of returning the current object, it returns a simple hash reference containing a copy of the current object data. Yes, thatβs the vibe.
β¨ as_json
Returns a JSON representation of the hash by calling json. Main character energy: it just delegates.
β¨ as_string
Returns a string version of the hash as produced by Data::Dumper.
print( "$h\n" );
# or
print( $h->as_string, "\n" );
# Produces
{
"age" => 30,
"email" => "john.doe\@example.com",
"first_name" => "John",
"last_name" => "Doe"
}
β¨ chomp
Performs chomp in perlfunc on the entire hash values and returns the current object it was called with. It does not chomp the keys, okay?
Quoting from perlfunc: βIf variable is a hash, it chomps the hash's values, but not its keysβ.
β¨ clone
Produces a deep clone of the hash and returns a new object. This uses clone in Clone to achieve that. Obsessed with a proper deep copy.
β¨ debug
Sets or gets the debug level. Simple as that.
β¨ defined
Provided with a hash key, this returns true if there is a value defined for this key. See defined in perlfunc.
β¨ delete
Provided with a hash key, this removes the hash entry and returns the previous value, exactly as delete in perlfunc does. Returns undef if the key does not exist:
my $value = $h->delete( "role" ); # Returns "customer" if it existed
β¨ dump
Returns a string representation of the hash. This uses Data::Dumper to produce the result.
β¨ each
Provided with a reference to a subroutine, this will do a loop using each in perlfunc, and it will call the code passing it the hash key and its value.
If the code returns false, it will exit the while in perlfunc loop.
To exit the loop, return undef(), for example:
$a->each(sub
{
my( $k, $v ) = @_;
return if( $key eq $not_this_one );
print( "ok, this one\n" );
});
β¨ exists
Given a hash key, this will return true or false depending on whether the hash key exists. This uses exists in perlfunc.
β¨ for
This is simply an alias for foreach. No cap.
β¨ foreach
Same as foreach in perlfunc: given a reference to a subroutine, this will execute foreach and call the code, providing the hash key and value as arguments. For convenience, $_ is also available and represents the 2nd argument, i.e. the value.
To exit the loop, return undef(), for example:
$a->foreach(sub
{
my( $k, $v ) = @_;
return if( $key eq $not_this_one );
print( "ok, this one\n" );
});
β¨ get
Provided with a hash key, this will return whatever value was set.
$a->get( 'last_name' ); # Return 'Doe' maybe?
See set for the opposite method, i.e. setting a key value.
β¨ has
Returns true if the given value exists in the hash. This is effectively an alias for exists.
β¨ is_empty
Returns true if the hash object contains no data, or false otherwise. Vibe check: empty or not.
β¨ json
This returns a JSON representation of the hash. You can optionally provide a hash reference of parameters.
All parameters supported by JSON can be used here.
For example:
my $json = $h->json({ pretty => 1, canonical => 1 });
# pretty only will trigger canonical to be true
my $json = $h->json({ pretty => 1 });
This would yield something like:
{
"age" : 30,
"email" : "john.doe@example.com",
"first_name" : "John",
"last_name" : "Doe"
}
Otherwise, you would get a more terse result, such as:
{"age":30,"email":"john.doe@example.com","first_name":"John","last_name":"Doe"}
When pretty is enabled, it will automatically also enable canonical, indent and relaxed unless those are explicitly specified:
my $json = $h->json({ pretty => 1, canonical => 0 });
For simplicity, you can also use, as an alias to canonical, sort, sorted, order or ordered.
It returns the JSON encoded data as a scalar object.
β¨ key_object
Sets or gets the boolean value as to whether this hash should allow the use of references as keys. Default is false.
When false, any reference used as a key will be converted to a string by Perl, since Perl natively does not recognise references as keys.
β¨ keys
Returns the hash keys as a Module::Generic::Array object.
Also note that if you have a multi-level hash, this will return only the first level keys, just like keys in perlfunc would do.
printf( "%d hash keys found\n", $h->keys->length );
And even chaining through different objects:
if( $h->keys->length->is_positive )
{
# Do something
}
This returns the keys as a Module::Generic::Array object, then returns the size of the array as a Module::Generic::Number object. So $h->keys->length is giving you that number object, iykyk.
β¨ length
This returns the number of keys in the hash, as a Module::Generic::Number object.
β¨ map
Provided with a code reference, this calls map in perlfunc and passes the code reference the hash key and its value.
It returns a regular list, i.e. not an object, just like Perlβs map in perlfunc would do. Returns an empty list if the code reference is invalid:
my @pairs = $h->map(sub
{
my( $k, $v ) = @_;
return( "$k=$v" );
}); # e.g., ("first_name=John", "last_name=Doe")
β¨ map_array
Does the same as map above, except it returns a new array as a Module::Generic::Array object.
my $pairs = $h->map_array(sub
{
my( $k, $v ) = @_;
return( "$k=$v" );
}); # e.g., ["first_name=John", "last_name=Doe"]
β¨ map_hash
Does the same as map above, except it returns a new Module::Generic::Hash object.
For this to work properly, the code reference needs to return a key-value pair.
my $new_h = $h->map_hash(sub
{
my( $k, $v ) = @_;
return( uc($k) => $v );
}); # e.g., { FIRST_NAME => "John", LAST_NAME => "Doe" }
β¨ md5
my $h = Module::Generic::Hash->new({ name => 'John Doe', age => 30 });
$h->md5; # 5930d8375b3aae2d2d063ad44142f297
$h->{location} = 'Tokyo';
$h->md5; # 1febee55cacfea22bb586dfc7eb61b7e
Returns the MD5 checksum of the underlying hash reference, useful for detecting changes. This uses Digest::MD5, which is a core Perl module and loaded dynamically, and JSON::XS (already a dependency), to ensure consistent checksums by sorting keys. It returns an error if those modules cannot be loaded.
You can also call this method as md5_checksum.
β¨ md5_checksum
This is an alias for md5.
β¨ md5_hex
This is an alias for md5.
β¨ merge
Provided with a hash reference and an optional hash of parameters, this will merge the given hash with the hash in our object. It does so recursively and prevents looping by using refaddr in Scalar::Util.
Currently the only parameter possible is overwrite. By default this is set to a true value, and you can provide this argument to specifically indicate you do not want the hash key value to be overwritten.
β¨ remove
Just an alias for delete.
β¨ reset
This simply empties the hash. See also undef for the same result.
β¨ set
Provided with a key and a value, and this adds it to the hash, possibly overwriting any previous entry.
See get for the opposite method, i.e. to get the key value.
β¨ size
Alias method for length.
β¨ undef
This simply empties the hash. See also reset for the same result.
β¨ values
This returns the values of the hash as a Module::Generic::Array, but please note that just like the values in perlfunc, it only provides the first level values.
If an optional reference to a subroutine is provided, the code will be called for each value as its sole argument, and the subroutine can decide what to do with it, possibly altering the value and discarding it by returning the value, possibly altered, or an empty list to indicate this entry should be discarded. For example:
my $vals = $h->values(sub{
ref( $_[0] ) ? () : $_[0];
});
This will make sure to get all values, except the ones that are references (perlref).
To return entries with uppercase first:
my $vals = $h->values(sub{
join( ' ', map( ucfirst( lc( $_ ) ), split( /[[:blank:]]+/, $_[0] ) ) );
});
And if one of the values were "JohN DOE", this would result in "John Doe".
If the parameter sort is provided, then it will sort the array before returning the values and before executing the reference of the subroutine on each entry.
π¦ 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.
use Storable;
my $h = Module::Generic::Hash->new( age => 30 );
my $frozen = Storable::freeze( $h );
my $thawed = Storable::thaw( $frozen );
print "Age: ", $thawed->{age}, "\n"; # 30
π THREAD-SAFETY π
okay so bestie, this is the part where we talk about threads, and ngl this is where a lot of people get humbled π. Here's the tea: Module::Generic::Hash is thread-safe for per-object operations, with proper handling of per-object state and external libraries. It supports multi-threaded environments, but β and this is the important part β care must be taken when sharing objects across threads or modifying global variables. Like, the vibes are fine until you start sharing. π
Key considerations for thread-safety, bestie, let's go:
πΈ Shared Variables
The global variable $KEY_OBJECT controls whether references can be used as hash keys. And the thing is, it is not shared by default, so concurrent modifications in threads may cause race conditions π. Use local or the key_object method to set it per-object, like so:
use threads;
my $h = Module::Generic::Hash->new;
$h->key_object(1); # Thread-safe per object
my $ref = [];
$h->{ $ref } = "array"; # Safe
See? Iconic. Doing it per-object is the moment. β¨
π¦ Hash Data
Hash data is stored in a tied hash (Module::Generic::TieHash), which is per-object and thread-safe for independent operations. Operations like merge, json, and clone operate on local data. But β and yes there's a but β concurrent modifications to a shared object are not thread-safe without synchronisation:
use threads;
my $h = Module::Generic::Hash->new( first_name => "John" );
lock( $h ); # Synchronize access
my @threads = map
{
threads->create(sub
{
lock( $h );
$h->merge({ last_name => "Doe" }); # Thread-safe with lock
});
} 1..5;
$_->join for( @threads );
For best practices β and this is the glow-up β create per-thread objects to avoid shared state entirely:
use threads;
my @threads = map
{
threads->create(sub
{
my $h = Module::Generic::Hash->new( first_name => "John" );
$h->merge({ last_name => "Doe" }); # Thread-safe
});
} 1..5;
$_->join for @threads;
No sharing, no drama. Main character energy. π
π External Libraries
Methods like json use JSON, clone uses Clone, and dump uses Data::Dumper β and all of those are thread-safe because they operate on per-object state. So go off, they're fine. π
π§ Serialisation
Serialisation methods (FREEZE, THAW) operate on per-object state, making them thread-safe:
use threads;
use Storable;
my $h = Module::Generic::Hash->new( age => 30 );
my $frozen = Storable::freeze( $h ); # Thread-safe
Freeze it, thaw it, slay it. π§
For debugging in threaded environments:
ls -l /proc/$$/fd # List open file descriptors
That's your little peek at what files are open, iykyk. π
β¨ SEE ALSO β¨
Go give these icons some love, bestie:
Module::Generic::ScalarModule::Generic::ArrayModule::Generic::BooleanModule::Generic::NumberModule::Generic::DynamicMath::BigInt
π AUTHOR π
Jacques Deguest <jack@deguest.jp> β shoutout to the author, fr fr π«Ά
π COPYRIGHT & LICENSE π
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. So like, go forth and build, just be normal about it π
Ok that's the whole page bestie, we did it!! π This masterpiece was served up by perl v5.42.2 and dated 2026-02-15 β literally stamped and everything. Mwah, go write some slay code πβ¨π
π¦ where this page comes from
- alpine 3.24: perl-module-generic-doc 1.1.3-r1 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms