Re: converting to a sub-class
by Joost (Canon) on Oct 20, 2007 at 17:57 UTC
|
Best practices, I don't know, but your construct is limited in that it will only work if the DUM::DUMMY::Whatever objects don't need any initialization (you're just blessing directly into that class).
What you're doing will work, though it may confuse people. The big question is, do you really need a DUM::DUMMY object at all, when you're going to move it to DUM::DUMMY::Whatever anyway?
If you can, I would prefer doing something like:
sub create {
my ($class,@options) = @_;
my $target_class = $class->find_class_for(@options);
return $target_class->new(@options);
}
and have find_class_for return the right package name (and possibly require it). That way the object returned can do whatever it needs to initialize itself - it doesn't even need to be a subclass of DUM::DUMMY.
Another thing to keep in mind, is that this still requires you to put all the knowledge about which class to choose in the base class. That isn't really "best practice", and it's possible to avoid it, but unless you're got many classes to choose from, it's probably the simplest way to do it like this.
| [reply] [d/l] |
|
|
I see where you're coming from with that, but I'm trying to take a class, then simply to specialise it in whatever way, ie, modified methods, or even new methods (although I doubt I'll be doing that).
I seem to be having a problem with this approach due to Class::Data::Inheritable and Class::Accessor
Those are both used in the base class for my 'initial' class to setup the constructor, etc.
those behaviours from the base class are present in the main class, but not in sub-classes when using the methods I've shown in my first example.
| [reply] |
Re: converting to a sub-class
by shmem (Chancellor) on Oct 20, 2007 at 19:48 UTC
|
I don't know about best-practice - as long as it works...
But a note on naming: that rather looks like a "factory class", not like "converting to a subclass".
If the class denominated by $self->{extension} has DUM::DUMMY in its @ISA, it is
a subclass of DUM::DUMMY. Does the following (add sanity checks for @_ and such) fit into your design?
package DUM::DUMMY;
use base 'DUM::Base';
sub new {
my $class = shift;
my %args = @_;
my $ext;
if ($ext = delete $args{extension} ) {
my $backend = 'DUM::DUMMY::'.$self->{extension};
eval "require $backend";
if ($@) {
# handle errors: die? return undef? set $@ ?
}
}
my $self = $class->SUPER::new(%args);
bless $self, 'DUM::DUMMY::'.$ext if $ext;
$self;
}
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] [d/l] [select] |
|
|
Thanks, much appreciated, but I think that's adding more to the situation, i think a lot of comments have.
I have My::Base.
My::Waffle uses My::Base a base class to sort out new() methods, etc, also using Class::Data::Inheritable and Class::Accessor to sort things out for me (this My::Base class wasn't developed by me, but quite the "O'Reilly developer" who was recently working with us.
I'm quite keen on just having My::Waffle::Whatever simply modify functionality from My::Waffle. The client will never know.
Does that make any sense? Think about the Person 'class' idea mentioned before with a person class, the client creates a My::Waffle object, which then uses different versions of methods depending on different properties assigned by the client.
Surely this can't be a new idea/feature wanted?
| [reply] |
|
|
mhm. Is that an issue of subclassing, of aggregation, or of mutiple inheritance? Difficult to tell
without synopsis.
See Anno's Alter package (RFC: Alter - Perl extension for Alter Ego Objects); may be that only adds to the confusion, but
I have a gut feeling it addresses your problem. Maybe I'm wrong.
If what you are doing is "method aggregation" (sorry for not using/knowing the canonical term for that),
- if you want to call a method based on an object's attribute, you could just use that attribute
to handle method dispatch via AUTOLOAD (which more aptly should be called AUTODISPATCH, since
loading is only one use for it, as in AutoLoader). The loading of that attribute's package would
have to be done in the object constructor.
Example:
sub AUTOLOAD {
return if $AUTOLOAD eq __PACKAGE__.'::'.'DESTROY';
my $self = shift;
(my $func = $AUTOLOAD) =~ s/.*:://;
if ($self->{extension}) {
my $method = join '::', __PACKAGE__, $self->{extension}, $func
+;
$method->($self,@_);
}
else {
die "method $func not defined for $self\n";
};
}
But that has the strong smell of reinventing a wheel. Method lookup based on object attribute? hmm...
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] [d/l] |
|
|
Re: converting to a sub-class
by gamache (Friar) on Oct 20, 2007 at 17:21 UTC
|
| [reply] |
|
|
In true OO fashion, imagine the 'base' class as a person, i want to create a subclass of a male person.
so i have
Person
and
Person::Male
I don't want anyone top create a Person::Male object directly, instead just create a Person object, and I'll subclass it to include new methods, or override common methods.
make sense? Am I missing something completely mental?
Thanks for your reply, although i was a bit shocked with "it's sick!" :-/
| [reply] |
|
|
| [reply] |
|
|
A reply falls below the community's threshold of quality. You may see it by logging in.
|