NAME
Extender - Dynamically enhance Perl objects with additional methods from other modules or custom subroutines
SYNOPSIS
use Extender;
# Example: Extend an object with methods from a module
my $object = MyClass->new();
Extend($object, 'Some::Class');
$object->method_from_some_class();
# Example: Extend an object with custom methods
Extends($object,
greet => sub { my ($self, $name) = @_; print "Hello, $name!\n"; },
custom_method => sub { return "Custom method executed"; },
);
$object->greet('Alice');
$object->custom_method();
DESCRIPTION
Extender is a Perl module that facilitates the dynamic extension of objects with methods from other modules or custom-defined subroutines. It allows you to enhance Perl objects—whether hash references, array references, or scalar references—with additional functionalities without altering their original definitions.
EXPORTED FUNCTIONS
Extend($object, $module, @methods)
Extends an object with methods from a specified module.
Arguments:
$object
- The object reference to which methods will be added.$module
- The name of the module from which methods will be imported.@methods
- Optional list of method names to import. If none are provided, all exported functions from$module
will be imported.
Description:
This function extends the specified $object
by importing methods from the module $module
. It dynamically loads the module if it's not already loaded, retrieves the list of exported functions, and adds each specified function as a method to the object.
Example:
use Extender;
# Create an object
my $object = {};
# Extend $object with methods from 'List::Util'
Extend($object, 'List::Util', 'sum', 'max');
# Now $object has 'sum' and 'max' methods from 'List::Util'
Extends($object, %extend)
Extends an object with custom methods.
Arguments:
$object
- The object reference to which methods will be added.%extend
- A hash where keys are method names and values are references to subroutines (CODE references). Alternatively, values can be references to scalars containing CODE references.
Description:
This function extends the specified $object
by adding custom methods defined in %extend
. Each key-value pair in %extend
corresponds to a method name and its associated subroutine reference. If the method name already exists in $object
, it will override it.
Example:
use Extender;
# Create an object
my $object = {};
# Define custom methods to extend $object
Extends($object,
custom_method => sub { return "Custom method" },
dynamic_method => \"sub { return 'Dynamic method' }",
);
# Now $object has 'custom_method' and 'dynamic_method'
Override($object, $method_name, $new_method)
Overrides an existing method in the object with a new implementation.
Arguments:
$object
- The object reference in which the method will be overridden.$method_name
- The name of the method to override.$new_method
- Reference to the new method implementation (CODE reference).
Description:
This function overrides an existing method in the object with a new implementation provided as $new_method
. It allows for dynamic replacement of method behavior in Perl objects.
Example:
use Extender;
my $object = {};
# Original method definition
sub original_method {
return "Original method";
}
# Override the 'original_method' in $object
Override($object, 'original_method', sub { return "New method"; });
# Using the overridden method
print $object->original_method(), "\n"; # Outputs: New method
Alias($object, $existing_method, $new_name)
Creates an alias for an existing method in the object with a new name.
Arguments:
$object
- The object reference in which the alias will be created.$existing_method
- The name of the existing method to alias.$new_name
- The new name for the alias.
Description:
This function creates an alias for an existing method in the object with a new name. It allows referencing the same method implementation using different names within the same object.
Example:
use Extender;
my $object = {};
# Original method definition
sub original_method {
return "Original method";
}
# Create an alias 'new_alias' for 'original_method' in $object
Alias($object, 'original_method', 'new_alias');
# Using the alias
print $object->new_alias(), "\n"; # Outputs: Original method
Unload($object, @methods)
Removes specified methods from the object's namespace.
Arguments:
$object
- The object reference from which methods will be removed.@methods
- List of method names to be removed from the object.
Description:
This function removes specified methods from the object's namespace. It effectively unloads or deletes methods that were previously added or defined within the object.
Example:
use Extender;
my $object = {};
# Define a method
sub example_method {
return "Example method";
}
# Extend $object with the method
Extend($object, 'ExampleModule', 'example_method');
# Unload the method from $object
Unload($object, 'example_method');
# Attempting to use the unloaded method will fail
eval {
$object->example_method(); # This will throw an error
};
if ($@) {
print "Error: $@\n";
}
AddMethod($object, $method_name, $code_ref)
Adds a new method to the object.
Arguments:
$object
- The object reference to which the method will be added.$method_name
- Name of the method to add. Must be a valid Perl subroutine name (word characters only).$code_ref
- Reference to the subroutine (code reference) that defines the method.
Description:
This function adds a new method to the object's namespace. It validates the method name and code reference before adding it to the object.
Example:
use Extender;
my $object = {};
# Define a new method
sub custom_method {
my ($self, $arg1, $arg2) = @_;
return "Custom method called with args: $arg1, $arg2";
}
# Add the method to $object
AddMethod($object, 'custom_method', \&custom_method);
# Using the added method
my $result = $object->custom_method('foo', 'bar');
print "$result\n"; # Outputs: Custom method called with args: foo, bar
Decorate($object, $method_name, $decorator)
Decorates an existing method of an object with a custom decorator.
Arguments:
$object
- The object reference whose method is to be decorated.$method_name
- The name of the method to decorate.$decorator
- A coderef representing the decorator function.
Description:
This function allows decorating an existing method of an object with a custom decorator function. The original method is replaced with a new subroutine that invokes the decorator function before and/or after invoking the original method.
Example:
use Extender;
# Define a decorator function
sub timing_decorator {
my ($self, $orig_method, @args) = @_;
my $start_time = time();
my $result = $orig_method->($self, @args);
my $end_time = time();
my $execution_time = $end_time - $start_time;
print "Execution time: $execution_time seconds\n";
return $result;
}
my $object = {};
$object->{counter} = 0;
# Add a method to increment a counter
$object->{increment} = sub { $object->{counter}++ };
# Decorate the 'increment' method with timing_decorator
Decorate($object, 'increment', \&timing_decorator);
# Invoke the decorated method
$object->increment();
# Output the counter value
print "Counter: ", $object->{counter}, "\n";
ApplyRole($object, $role_class)
Applies a role (mixin) to an object, importing and applying its methods.
Arguments:
$object
- The object reference to which the role will be applied.$role_class
- The name of the role class to be applied.
Description:
This function loads a role class using require
, imports its methods into the current package, and applies them to the object using apply
.
Example:
use Extender;
# Define a role (mixin)
package MyRole;
sub foo { print "foo\n" }
sub bar { print "bar\n" }
# Apply the role to an object
my $object = {};
ApplyRole($object, 'MyRole');
# Call the role methods
$object->foo(); # Outputs: foo
$object->bar(); # Outputs: bar
InitHook($object, $hook_name, $hook_code)
Adds initialization or destruction hooks to an object.
Arguments:
$object
- The object reference to which the hook will be added.$hook_name
- The type of hook to add. Valid values are 'INIT' for initialization and 'DESTRUCT' for destruction.$hook_code
- A code reference to the hook function to be executed.
Description:
This function adds a code reference to the specified hook array (`_init_hooks` or `_destruct_hooks`) in the object. Hooks can be executed during object initialization or destruction phases.
Example:
package MyClass;
sub new {
my ($class)=@_;
my $self={};
# Add initialization hook
InitHook($self, 'INIT', sub {
print "Object initialized\n";
});
# Add destruction hook
InitHook($self, 'DESTRUCT', sub {
print "Object destroyed\n";
});
return bless $self, $class
}
use Extender;
# Create an object
my $object = MyClass->new();
# Destroy an object
undef $object;
GenerateMethod($object, $method_name, $generator_code)
Generates a method on an object using a generator code reference.
Arguments:
$object
- The object reference to which the method will be added.$method_name
- The name of the method to generate.$generator_code
- A code reference that generates the method's functionality.
Description:
This function dynamically generates a new method on the specified object using the provided generator code reference (`$generator_code`). The generator code receives the object reference (`$self`) as the first argument, followed by any additional arguments passed to the method.
Example:
use Extender;
# Create an object
my $object = {};
# Define a generator code reference
my $generator = sub {
my ($self, $arg1, $arg2) = @_;
return $arg1 + $arg2;
};
# Generate a new method 'add' on the object using the generator code
GenerateMethod($object, 'add', $generator);
# Call the generated method
my $result = $object->add(3, 4); # $result will be 7
MooseCompat($object, $role_name)
Applies a Moose role to an object using MooseX::Role::Parameterized::Extender::$role_name.
Arguments:
$object
- The object reference to which the role will be applied.$role_name
- The name of the Moose role to apply.
Description:
This function attempts to apply a Moose role specified by $role_name
to the given object $object
. It dynamically loads the Moose role module using require
, applies it to the object, and handles any errors that occur during this process.
Example:
use Extender;
# Create an object
my $object = {};
# Apply a Moose role 'Logger' to the object
MooseCompat($object, 'Logger');
# Now $object has the capabilities provided by the 'Logger' role
USAGE
Extend an Object with Methods from a Module
use Extender;
# Extend an object with methods from a module
my $object = MyClass->new();
Extend($object, 'Some::Class');
# Now $object can use any method from Some::Class
$object->method1(1, 2, 3, 4);
Extend an Object with Custom Methods
use Extender;
# Extend an object with custom methods
my $object = MyClass->new();
Extends($object,
greet => sub { my ($self, $name) = @_; print "Hello, $name!\n"; },
custom_method => \&some_function,
);
# Using the added methods
$object->greet('Alice'); # Output: Hello, Alice!
$object->custom_method('Hello'); # Assuming some_function prints something
Adding Methods to Raw Reference Variables
package HashMethods;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw(set get);
sub set {
my ($self, $key, $value) = @_;
$self->{$key} = $value;
}
sub get {
my ($self, $key) = @_;
return $self->{$key};
}
1;
package ArrayMethods;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw(add get);
sub add {
my ($self, $item) = @_;
push @$self, $item;
}
sub get {
my ($self, $index) = @_;
return $self->[$index];
}
1;
package ScalarMethods;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw(set get substr length);
sub set {
my ($self, $value) = @_;
$$self = $value;
}
sub get {
my ($self) = @_;
return $$self;
}
sub substr {
my $self = shift;
return substr($$self, @_);
}
sub length {
my ($self) = @_;
return length $$self;
}
1;
# MAIN
package main;
use strict;
use warnings;
use Extender;
use HashMethods;
use ArrayMethods;
use ScalarMethods;
my $hash_object = {};
my $array_object = [];
my $scalar_object = \"";
# Extend $hash_object with methods from HashMethods
Extend($hash_object, 'HashMethods', 'set', 'get');
# Extend $array_object with methods from ArrayMethods
Extend($array_object, 'ArrayMethods', 'add', 'get');
# Extend $scalar_object with methods from ScalarMethods
Extend($scalar_object, 'ScalarMethods', 'set', 'get', 'substr', 'length');
# Using extended methods for hash object
$hash_object->set('key', 'value');
print $hash_object->get('key'), "\n"; # Outputs: value
# Using extended methods for array object
$array_object->add('item1');
$array_object->add('item2');
print $array_object->get(0), "\n"; # Outputs: item1
# Using extended methods for scalar object
$scalar_object->set('John');
print $scalar_object->get(), "\n"; # Outputs: John
print $scalar_object->length(), "\n"; # Outputs: 4
print $scalar_object->substr(1, 2), "\n"; # Outputs: oh
$scalar_object->substr(1, 2, "ane");
print $scalar_object->get(), "\n"; # Outputs: Jane
1;
Adding methods using anonymous subroutines and existing functions
use Extender;
package MyClass;
sub new {
my $class = shift;
my $self = bless {}, $class;
return $self;
}
my $object = MyClass->new();
Extends($object,
greet => sub { my ($self, $name) = @_; print "Hello, $name!\n"; },
custom_method => \&some_function,
);
# Using the added methods
$object->greet('Alice'); # Output: Hello, Alice!
$object->custom_method('Hello'); # Assuming some_function prints something
Using Shared Object for Shared Variable functionality
package main;
use strict;
use warnings;
use threads;
use threads::shared;
use Extender;
# Example methods to manipulate shared data
# Method to set data in a shared hash
sub set_hash_data {
my ($self, $key, $value) = @_;
lock(%{$self});
$self->{$key} = $value;
}
# Method to get data from a shared hash
sub get_hash_data {
my ($self, $key) = @_;
lock(%{$self});
return $self->{$key};
}
# Method to add item to a shared array
sub add_array_item {
my ($self, $item) = @_;
lock(@{$self});
push @{$self}, $item;
}
# Method to get item from a shared array
sub get_array_item {
my ($self, $index) = @_;
lock(@{$self});
return $self->[$index];
}
# Method to set data in a shared scalar
sub set_scalar_data {
my ($self, $value) = @_;
lock(${$self});
${$self} = $value;
}
# Method to get data from a shared scalar
sub get_scalar_data {
my ($self) = @_;
lock(${$self});
return ${$self};
}
# Create shared data structures
my %shared_hash :shared;
my @shared_array :shared;
my $shared_scalar :shared;
# Create shared objects
my $shared_hash_object = \%shared_hash;
my $shared_array_object = \@shared_array;
my $shared_scalar_object = \$shared_scalar;
# Extend the shared hash object with custom methods
Extends($shared_hash_object,
set_hash_data => \&set_hash_data,
get_hash_data => \&get_hash_data,
);
# Extend the shared array object with custom methods
Extends($shared_array_object,
add_array_item => \&add_array_item,
get_array_item => \&get_array_item,
);
# Extend the shared scalar object with custom methods
Extends($shared_scalar_object,
set_scalar_data => \&set_scalar_data,
get_scalar_data => \&get_scalar_data,
);
# Create threads to manipulate shared objects concurrently
# Thread for shared hash object
my $hash_thread = threads->create(sub {
$shared_hash_object->set_hash_data('key1', 'value1');
print "Hash thread: key1 = " . $shared_hash_object->get_hash_data('key1') . "\n";
});
# Thread for shared array object
my $array_thread = threads->create(sub {
$shared_array_object->add_array_item('item1');
print "Array thread: item at index 0 = " . $shared_array_object->get_array_item(0) . "\n";
});
# Thread for shared scalar object
my $scalar_thread = threads->create(sub {
$shared_scalar_object->set_scalar_data('shared_value');
print "Scalar thread: value = " . $shared_scalar_object->get_scalar_data() . "\n";
});
# Wait for all threads to finish
$hash_thread->join();
$array_thread->join();
$scalar_thread->join();
1;
Updating existing methods on an object class
package MyClass;
sub new {
my $class = shift;
my $self = bless {}, $class;
return $self;
}
sub original_method {
return "Original method";
}
package main;
use Extender;
my $object = MyClass->new();
# Define a method with the same name as an existing method
Extends($object,
original_method => sub { return "New method"; },
);
# Using the extended method
print $object->original_method(), "\n"; # Outputs: New method
1;
AUTHOR
OnEhIppY @ Domero Software <domerosoftware@gmail.com>
LICENSE
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic and perlgpl.
SEE ALSO
Exporter, perlfunc, perlref, perlsub
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 35:
Non-ASCII character seen before =encoding in 'objects—whether'. Assuming UTF-8