1 # This module is part of DA, Don Armstrong's Modules, and is released
2 # under the terms of the GPL version 2, or any later version. See the
3 # file README and COPYING for more information.
4 # Copyright 2003,2004 by Don Armstrong <don@donarmstrong.com>.
7 package Class::Modular;
11 Class::Modular -- Modular class generation superclass
17 use base qw(Class::Modular);
21 my $self = bless {}, ref($class) || $class;
22 $self->SUPER::_init(@_);
30 sub method_that_bar_provides{
31 print qq(Hello World!\n);
35 return qw(method_that_bar_provides);
44 $foo->method_that_bar_provides;
49 Class::Modular is a superclass for generating modular classes, where
50 methods can be added into the class from the perspective of the
51 object, rather than the perspective of the class.
53 That is, you can create a class which has a set of generic common
54 functions. Less generic functions can be included or overridden
55 without modifying the base classes. This allows for code to be more
56 modular, and reduces code duplication.
58 This module attempts to fill the middle ground between
59 L<Class::Mutator> and true classless OOP, like L<Class::Classless>.
66 use vars qw($VERSION $DEBUG $REVISION $USE_SAFE);
70 use Storable qw(dclone); # Used for deep copying objects
71 use Safe; # Use Safe when we are dealing with coderefs
74 $VERSION = q$0.03SVN$;
75 ($REVISION) = q$LastChangedRevision$ =~ /\$LastChangedRevision:\s+([^\s+])/;
76 $DEBUG = 0 unless defined $DEBUG;
77 $USE_SAFE = 1 unless defined $USE_SAFE;
80 # This is the class_modular namespace, so we don't muck up the
81 # subclass(es) by accident.
83 my $cm = q(__class_modular);
90 $db->load('FOO::Subclass');
92 Loads the named subclass into this object if the named subclass has
95 The options scalar is passed to $subclass::_methods when determining
96 which methods should be added using _addmethods.
98 The subclasses _init method is called right after methods are loaded.
100 If debugging is enabled, will warn about loading already loaded
106 my ($self,$subclass,$options) = @_;
110 # check to see if the subclass has already been loaded.
112 if (not defined $self->{$cm}{_subclasses}{$subclass}){
115 # Yeah, I don't care if calling an inherited AUTOLOAD
116 # for a non method is deprecated. Bite me.
117 no warnings 'deprecated';
118 eval "require $subclass" or die $@;
119 $self->_addmethods($subclass,&{"${subclass}::_methods"}($self,$options));
120 &{"${subclass}::_init"}($self);
122 die $@ if $@ and $@ !~ /^Undefined function ${subclass}::_init at [^\n]*$/;
123 $self->{$cm}{_subclasses}{$subclass} = {};
126 carp "Not reloading subclass $subclass" if $DEBUG;
133 $obj->override('methodname', $code_ref)
135 Allows you to override utility functions that are called internally to
136 provide a different default function. It's superficially similar to
137 _addmethods, which is called by load, but it deals with code
138 references, and requires the method name to be known.
140 Methods overridden here are _NOT_ overrideable in _addmethods. This
141 may need to be changed.
146 my ($self, $method_name, $function_reference) = @_;
148 $self->{$cm}{_methodhash}{$method_name}{reference} = $function_reference;
149 $self->{$cm}{_methodhash}{$method_name}{overridden} = 1;
155 my $clone = $obj->clone
157 Produces a clone of the object with duplicates of all data and/or new
158 connections as appropriate.
160 Calls _clone on all loaded subclasses.
162 Warns if debugging is on for classes which don't have a _clone method.
163 Dies on other errors.
165 clone uses L<Safe> to allow L<Storable> to deparse code references
166 sanely. Set C<$Class::Modular::USE_SAFE = 0> to disable this. [Doing
167 this may cause errors from Storable about CODE references.]
175 bless $clone, ref($self);
177 # copy data structures at this level
178 if ($self->{$cm}{use_safe}) {
180 $safe->permit(qw(:default require));
181 local $Storable::Deparse = 1;
182 local $Storable::Eval = sub { $safe->reval($_[0]) };
183 $clone->{$cm}{_methodhash} = dclone($self->{$cm}{_methodhash});
184 $clone->{$cm}{_subclasses} = dclone($self->{$cm}{_subclasses});
187 $clone->{$cm}{_methodhash} = dclone($self->{$cm}{_methodhash});
188 $clone->{$cm}{_subclasses} = dclone($self->{$cm}{_subclasses});
191 foreach my $subclass (keys %{$self->{$cm}{_subclasses}}) {
192 # Find out if the subclass has a clone method.
193 # If it does, call it, die on errors.
194 my $function = UNIVERSAL::can($subclass, '_clone');
197 # No, I could care less that AUTOLOAD is
198 # deprecated. Eat me.
199 no warnings 'deprecated';
200 &{"${subclass}::_clone"}($self,$clone);
203 # Die unless we've hit an undefined subroutine.
204 if ($@ !~ /^Undefined function ${subclass}::_clone at [^\n]*$/){
205 die "Failed while trying to clone: $@";
208 carp "No _clone method defined for $subclass" if $DEBUG;
218 Class::Modular->can('METHOD');
220 Replaces UNIVERSAL's can method so that handled methods are reported
221 correctly. Calls UNIVERSAL::can in the places where we don't know
224 Returns a coderef to the method if the method is supported, undef
230 my ($self,$method,$vars) = @_;
232 croak "Usage: can(object-ref, method, [vars]);\n" if not defined $method;
234 if (ref $self and exists $self->{$cm}{_methodhash}->{$method}) {
235 # If the method is defined, return a reference to the
237 return $self->{$cm}{_methodhash}{$method}{reference};
240 # Otherwise, let UNIVERSAL::can deal with the method
242 return UNIVERSAL::can($self,$method);
249 $obj->handledby('methodname');
250 $obj->handledby('Class::Method::methodname');
252 Returns the subclass that handles the method methodname.
257 my ($self,$method_name) = @_;
259 $method_name =~ s/.*\://;
261 if (exists $self->{$cm}{_methodhash}{$method_name}) {
262 return $self->{$cm}{_methodhash}{$method_name}{subclass};
270 $obj = Foo::Bar->new(qw(baz quux));
272 Creates a new Foo::Bar object
274 Aditional arguments can be passed to this creator, and they are stored
275 in $self->{creation_args} (and $self->{$cm}{creation_args} by
278 This new function creates an object of Class::Modular, and calls the
279 C<$self->load(Foo::Bar)>, which will typically do what you want.
281 If you override this method in your subclasses, you will not be able
282 to use override to override methods defined within those
283 subclasses. This may or may not be a feature. You must also call
284 C<$self->SUPER::_init(@_)> if you override new.
289 my ($class,@args) = @_;
291 # We shouldn't be called $me->new, but just in case
292 $class = ref($class) || $class;
296 # But why, Don, are you being evil and not using the two argument
299 # My child, we always want to go to Class::Modular first,
300 # otherwise we will be unable to override methods in subclasses.
302 # But doesn't this mean that subclasses won't be able to override
305 # Only if they don't also override new!
307 bless $self, 'Class::Modular';
311 # Now we call our subclass's load routine so that our evil deeds
320 =head1 FUNCTIONS YOU PROBABLY DON'T CARE ABOUT
326 Calls all subclass _destroy methods.
328 Subclasses need only implement a _destroy method if they have
329 references that need to be uncircularized, or things that should be
330 disconnected or closed.
336 foreach my $subclass (keys %{$self->{$cm}{_subclasses}}) {
337 # use eval to try and call the subclasses _destroy method.
338 # Ignore no such function errors, but trap other types of
342 # Shove off, deprecated AUTOLOAD warning!
343 no warnings 'deprecated';
344 &{"${subclass}::_destroy"}($self);
347 if ($@ !~ /^Undefined (function|subroutine) \&?${subclass}::_destroy (|called )at [^\n]*$/){
348 die "Failed while trying to destroy: $@";
351 carp "No _destroy method defined for $subclass" if $DEBUG;
360 The AUTOLOAD function is responsible for calling child methods which
361 have been installed into the current Class::Modular handle.
363 Subclasses that have a new function as well as an AUTOLOAD function
364 must call Class::Modular::AUTOLOAD and set $Class::Modular::AUTOLOAD
366 $Class::Modular::AUTOLOAD = $AUTOLOAD;
367 goto &Class::Modular::AUTOLOAD;
369 Failure to do the above will break Class::Modular utterly.
374 my $method = $AUTOLOAD;
380 if (not ref($self)) {
381 carp "Not a reference in AUTOLOAD.";
385 if (exists $self->{$cm}{_methodhash}{$method} and
386 defined $self->{$cm}{_methodhash}{$method}{reference}) {
389 goto &{$self->{$cm}{_methodhash}{$method}{reference}};
393 croak "Undefined function $AUTOLOAD";
401 Stores the arguments used at new so modules that are loaded later can
402 read them from B<creation_args>
404 You can also override this method, but if you do so, you should call
405 Class::Modular::_init($self,@_) if you don't set creation_args.
410 my ($self,@creation_args) = @_;
412 my $creation_args = [@_];
413 $self->{creation_args} = $creation_args if not exists $self->{creation_args};
415 # Make another reference to this, so we can get it if a subclass
416 # overwrites it, or if it was already set for some reason
417 $self->{$cm}->{creation_args} = $creation_args;
418 $self->{$cm}->{use_safe} = $USE_SAFE;
426 Given an array of methods, adds the methods into the _methodhash
429 Methods that have previously been overridden by override are _NOT_
430 overridden again. This may need to be adjusted in load.
434 sub _addmethods($@) {
435 my ($self,$subclass,@methods) = @_;
437 # stick the method into the table
438 # DLA: Make with the munchies!
440 foreach my $method (@methods) {
441 if (not $method =~ /^$subclass/) {
442 $method = $subclass.'::'.$method;
444 my ($method_name) = $method =~ /\:*([^\:]+)\s*$/;
445 if (exists $self->{$cm}{_methodhash}{$method_name}) {
446 if ($self->{$cm}{_methodhash}{$method_name}{overridden}) {
447 carp "Not overriding already overriden method $method_name\n" if $DEBUG;
450 carp "Overriding $method_name $self->{$cm}{_methodhash}{$method_name}{reference} with $method\n";
452 $self->{$cm}{_methodhash}{$method_name}{reference} = $method;
453 $self->{$cm}{_methodhash}{$method_name}{subclass} = $subclass;
466 Because this module works through AUTOLOAD, utilities that use
467 can($object) instead of $object->can() will fail to see routines that
468 are actually there. Params::Validate, an excellent module, is
469 currently one of these offenders.
473 This module is part of DA, Don Armstrong's Modules, and is released
474 under the terms of the GPL version 2, or any later version. See the
475 file README and COPYING for more information.
477 Copyright 2003, 2004 by Don Armstrong <don@donarmstrong.com>