summaryrefslogtreecommitdiff
path: root/lib/Class/MakeMethods/Emulator.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Class/MakeMethods/Emulator.pm')
-rw-r--r--lib/Class/MakeMethods/Emulator.pm165
1 files changed, 165 insertions, 0 deletions
diff --git a/lib/Class/MakeMethods/Emulator.pm b/lib/Class/MakeMethods/Emulator.pm
new file mode 100644
index 0000000..96786da
--- /dev/null
+++ b/lib/Class/MakeMethods/Emulator.pm
@@ -0,0 +1,165 @@
+package Class::MakeMethods::Emulator;
+
+$VERSION = 1.009;
+
+########################################################################
+### IMPORT BEHAVIOR: import(), _handle_namespace()
+########################################################################
+
+@EXPORT_OK = qw( namespace_capture namespace_release );
+sub import {
+
+ if ( scalar @_ == 2 and $_[1] eq '-isasubclass' ) {
+ splice @_, 1, 1;
+ my $target_class = ( caller )[0];
+ no strict;
+ push @{"$target_class\::ISA"}, $_[0];
+ }
+
+ if ( $_[0] eq __PACKAGE__ ) {
+ require Exporter and goto &Exporter::import # lazy Exporter
+ }
+}
+
+sub _handle_namespace {
+ my $class = shift;
+ my $emulation_target = shift;
+ my $firstarg = shift or return;
+ my $take = shift || '-take_namespace';
+ my $release = shift || '-release_namespace';
+
+ if ( $firstarg eq $take) {
+ Class::MakeMethods::Emulator::namespace_capture($class, $emulation_target);
+ return 1;
+ } elsif ( $firstarg eq $release) {
+ Class::MakeMethods::Emulator::namespace_release($class, $emulation_target);
+ return 1;
+ }
+}
+
+########################################################################
+### NAMESPACE MUNGING: _namespace_capture(), _namespace_release()
+########################################################################
+
+sub namespace_capture {
+ my $source_package = shift;
+ my $target_package = shift;
+
+ # warn "Mapping $source_package over $target_package \n";
+
+ my $source_file = "$source_package.pm";
+ $source_file =~ s{::}{/}g;
+
+ my $target_file = "$target_package.pm";
+ $target_file =~ s{::}{/}g;
+
+ my $temp_package = $source_package . '::Target::' . $target_package;
+ my $temp_file = "$temp_package.pm";
+ $temp_file =~ s{::}{/}g;
+
+ no strict;
+ unless ( ${$temp_package . "::TargetCaptured"} ++ ) {
+ *{$temp_package . "::"} = *{$target_package . "::"};
+ $::INC{$temp_file} = $::INC{$target_file};
+ }
+ *{$target_package . "::"} = *{$source_package . "::"};
+ $::INC{$target_file} = $::INC{$source_file}
+}
+
+sub namespace_release {
+ my $source_package = shift;
+ my $target_package = shift;
+
+ my $target_file = "$target_package.pm";
+ $target_file =~ s{::}{/}g;
+
+ my $temp_package = $source_package . '::Target::' . $target_package;
+ my $temp_file = "$temp_package.pm";
+ $temp_file =~ s{::}{/}g;
+
+ no strict;
+ unless ( ${"${temp_package}::TargetCaptured"} ) {
+ Carp::croak("Can't _namespace_release: -take_namespace not called yet.");
+ }
+ *{$target_package . "::"} = *{$temp_package. "::"};
+ $::INC{$target_file} = $::INC{$temp_file};
+}
+
+########################################################################
+
+1;
+
+__END__
+
+
+=head1 NAME
+
+Class::MakeMethods::Emulator - Demonstrate class-generator equivalency
+
+
+=head1 SYNOPSIS
+
+ # Equivalent to use Class::Singleton;
+ use Class::MakeMethods::Emulator::Singleton;
+
+ # Equivalent to use Class::Struct;
+ use Class::MakeMethods::Emulator::Struct;
+ struct ( ... );
+
+ # Equivalent to use Class::MethodMaker( ... );
+ use Class::MakeMethods::Emulator::MethodMaker( ... );
+
+ # Equivalent to use base 'Class::Inheritable';
+ use base 'Class::MakeMethods::Emulator::Inheritable';
+ MyClass->mk_classdata( ... );
+
+ # Equivalent to use base 'Class::AccessorFast';
+ use base 'Class::MakeMethods::Emulator::AccessorFast';
+ MyClass->mk_accessors(qw(this that whatever));
+
+ # Equivalent to use accessors( ... );
+ use Class::MakeMethods::Emulator::accessors( ... );
+
+ # Equivalent to use mcoder( ... );
+ use Class::MakeMethods::Emulator::mcoder( ... );
+
+
+=head1 DESCRIPTION
+
+In several cases, Class::MakeMethods provides functionality closely
+equivalent to that of an existing module, and it is simple to map
+the existing module's interface to that of Class::MakeMethods.
+
+Class::MakeMethods::Emulator provides emulators for Class::MethodMaker,
+Class::Accessor::Fast, Class::Data::Inheritable, Class::Singleton,
+Class::Struct, accessors, and mcoder, each of which passes the
+original module's test suite, usually requiring only the addition
+of a a single line to each test, activating the emulation module.
+
+Beyond demonstrating compatibility, these emulators also generally
+indicate the changes needed to switch to direct use of Class::MakeMethods
+functionality, illustrate commonalities between the various modules,
+and serve as a source for new ideas that can be integrated into
+Class::MakeMethods.
+
+
+=head1 SEE ALSO
+
+See L<Class::MakeMethods> for general information about this distribution.
+
+See L<Class::MakeMethods::Emulator::accessors>, and L<accessors> from CPAN.
+
+See L<Class::MakeMethods::Emulator::Struct>, and L<Class::Struct> from CPAN.
+
+See L<Class::MakeMethods::Emulator::AccessorFast>, and L<Class::Accessor::Fast> from CPAN.
+
+See L<Class::MakeMethods::Emulator::Inheritable>, and L<Class::Data::Inheritable> from CPAN.
+
+See L<Class::MakeMethods::Emulator::MethodMaker>, and L<Class::MethodMaker> from CPAN.
+
+See L<Class::MakeMethods::Emulator::Singleton>, and L<Class::Singleton> from CPAN.
+
+See L<Class::MakeMethods::Emulator::mcoder>, and L<mcoder> from CPAN.
+
+=cut
+