From bcbf441e09fb502cf64924ff2530fa144bdf52c5 Mon Sep 17 00:00:00 2001 From: Andreas Brachold Date: Mon, 13 Aug 2007 18:41:27 +0000 Subject: * Move files to trunk --- lib/Class/MakeMethods/Template/Ref.pm | 207 ++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 lib/Class/MakeMethods/Template/Ref.pm (limited to 'lib/Class/MakeMethods/Template/Ref.pm') diff --git a/lib/Class/MakeMethods/Template/Ref.pm b/lib/Class/MakeMethods/Template/Ref.pm new file mode 100644 index 0000000..d97bafa --- /dev/null +++ b/lib/Class/MakeMethods/Template/Ref.pm @@ -0,0 +1,207 @@ +=head1 NAME + +Class::MakeMethods::Template::Ref - Universal copy and compare methods + +=head1 SYNOPSIS + + package MyObject; + use Class::MakeMethods::Template::Ref ( + 'Hash:new' => [ 'new' ], + clone => [ 'clone' ] + ); + + package main; + + my $obj = MyObject->new( foo => ["Foozle", "Bozzle"] ); + my $clone = $obj->clone(); + print $obj->{'foo'}[1]; + +=cut + +package Class::MakeMethods::Template::Ref; + +$VERSION = 1.008; +use strict; +require 5.00; +use Carp; + +use Class::MakeMethods::Template '-isasubclass'; +use Class::MakeMethods::Utility::Ref qw( ref_clone ref_compare ); + +###################################################################### + +=head1 DESCRIPTION + +The following types of methods are provided via the Class::MakeMethods interface: + +=head2 clone + +Produce a deep copy of an instance of almost any underlying datatype. + +Parameters: + +init_method + +If defined, this method is called on the new object with any arguments passed in. + +=cut + +sub clone { + { + 'params' => { 'init_method' => '' }, + 'interface' => { + default => 'clone', + clone => { '*'=>'clone', }, + }, + 'behavior' => { + 'clone' => sub { my $m_info = $_[0]; sub { + my $callee = shift; + ref $callee or croak "Can only copy instances, not a class.\n"; + + my $self = ref_clone( $callee ); + + my $init_method = $m_info->{'init_method'}; + if ( $init_method ) { + $self->$init_method( @_ ); + } elsif ( scalar @_ ) { + croak "No init_method"; + } + return $self; + }}, + }, + } +} + +###################################################################### + +=head2 prototype + +Create new instances by making a deep copy of a static prototypical instance. + +Parameters: + +init_method + +If defined, this method is called on the new object with any arguments passed in. +=cut + +sub prototype { + ( { + 'interface' => { + default => { '*'=>'set_or_new', }, + }, + 'behavior' => { + 'set_or_new' => sub { my $m_info = $_[0]; sub { + my $class = shift; + + if ( scalar @_ == 1 and UNIVERSAL::isa( $_[0], $class ) ) { + # set + $m_info->{'instance'} = shift + + } else { + # get + croak "Prototype is not defined" unless $m_info->{'instance'}; + my $self = ref_clone($m_info->{'instance'}); + + my $init_method = $m_info->{'init_method'}; + if ( $init_method ) { + $self->$init_method( @_ ); + } elsif ( scalar @_ ) { + croak "No init_method"; + } + return $self; + } + }}, + 'set' => sub { my $m_info = $_[0]; sub { + my $class = shift; + $m_info->{'instance'} = shift + }}, + 'new' => sub { my $m_info = $_[0]; sub { + my $class = shift; + + croak "Prototype is not defined" unless $m_info->{'instance'}; + my $self = ref_clone($m_info->{'instance'}); + + my $init_method = $m_info->{'init_method'}; + if ( $init_method ) { + $self->$init_method( @_ ); + } elsif ( scalar @_ ) { + croak "No init_method"; + } + return $self; + }}, + }, + } ) +} + +###################################################################### + +=head2 compare + +Compare one object to another. + +B + +=over 4 + +=item * + +default + +Three-way (sorting-style) comparison. + +=item * + +equals + +Are these two objects equivalent? + +=item * + +identity + +Are these two references to the exact same object? + +=back + +=cut + +sub compare { + { + 'params' => { 'init_method' => '' }, + 'interface' => { + default => { '*'=>'compare', }, + equals => { '*'=>'equals', }, + identity => { '*'=>'identity', }, + }, + 'behavior' => { + 'compare' => sub { my $m_info = $_[0]; sub { + my $callee = shift; + ref_compare( $callee, shift ); + }}, + 'equals' => sub { my $m_info = $_[0]; sub { + my $callee = shift; + ref_compare( $callee, shift ) == 0; + }}, + 'identity' => sub { my $m_info = $_[0]; sub { + $_[0] eq $_[1] + }}, + }, + } +} + +###################################################################### + +=head1 SEE ALSO + +See L for general information about this distribution. + +See L for more about this family of subclasses. + +See L for the clone and compare functions used above. + +=cut + +###################################################################### + +1; -- cgit v1.2.3