NAME
Marlin::X::Clone - Marlin extension to add a clone method to your class.
SYNOPSIS
package Local::Date {
use Marlin qw( year month day :Clone );
}
my $xmas = Local::Date->new( day => 25, month => 12, year => 2025 );
my $xmas_eve = $xmas->clone( day => 24 );
DESCRIPTION
This package creates a method in your class that does roughly:
sub clone {
my ( $self, %args ) = @_;
my %clone = ( %$self, %args );
return bless \%clone, ref($self);
}
Except it also:
Skips over "PRIVATE" storage attributes by default.
Respects the
init_argfor each attribute.Calls trigger methods, uses defaults, checks type constraints, and does type coercions.
Allows per-attribute tweaks to its behaviour.
Calls
BUILDmethods.Complains if you give it arguments which it doesn't recognize.
You can tweak an attribute's behaviour using:
use Marlin foo => { on_clone => ... };
Valid values for on_clone:
:simple-
A simple shallow copy. If the value is a reference, the cloned value will refer to the same data.
## on_clone => ':simple' $clone->{foo} = $self->{foo};This is the default and will be used if
on_cloneis omitted, or foron_clone => true. :deep-
Uses the Clone module to make a deep clone of the original value.
## on_clone => ':deep' $clone->{foo} = Clone::clone( $self->{foo} ); :none-
Does not clone the attribute value.
You can also specify this as
on_clone => false. :methodor:method(NAME)-
Calls a method on the original value, assuming it's a blessed object. If the original value is not a blessed object, it will silently be skipped. If no
NAMEis provided, the name is assumed to be "clone".## on_clone => ':method' if ( blessed $self->{foo} ) { $clone->{foo} = $self->{foo}->clone; } ## on_clone => ':method(make_copy)' if ( blessed $self->{foo} ) { $clone->{foo} = $self->{foo}->make_copy; } :selfmethod(NAME)-
Calls a method on the original object.
## on_clone => ':selfmethod(make_copy)' $clone->{foo} = $self->make_copy( foo => $self->{foo} );You can also specify this as
on_clone => "NAME"as a shortcut. - CODE
-
Setting
on_clone => sub {...}will call the coderef in a similar style to:selfmethod.## on_clone => $coderef $clone->{foo} = $self->$coderef( foo => $self->{foo} );
Because :method only works when the value is a blessed object, you can indicate a fallback that will be used in other cases.
## on_clone => ':method(make_copy) :deep'
if ( blessed $self->{foo} ) {
$clone->{foo} = $self->{foo}->make_copy;
}
else {
$clone->{foo} = Clone::clone( $self->{foo} );
}
## on_clone => ':method(make_copy) :copy'
if ( blessed $self->{foo} ) {
$clone->{foo} = $self->{foo}->make_copy;
}
else {
$clone->{foo} = $self->{foo};
}
## on_clone => ':method(make_copy) :none'
if ( blessed $self->{foo} ) {
$clone->{foo} = $self->{foo}->make_copy;
}
You can also set a few options for how the plugin behaves:
use Marlin qw( foo bar ),
':Clone' => {
method_name => 'clone', # Name for the clone method
call_build => true, # Call BUILD after cloning?
strict_args => true, # Complain about unrecognized params?
};
This module also acts as a demonstration of Marlin's extension API. See comments in the source code for more details.
BUGS
Please report any bugs to https://github.com/tobyink/p5-marlin/issues.
SEE ALSO
AUTHOR
Toby Inkster <tobyink@cpan.org>.
COPYRIGHT AND LICENCE
This software is copyright (c) 2025 by Toby Inkster.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
DISCLAIMER OF WARRANTIES
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
🐟🐟