Possible Duplicate:
How to have Moose return a child class instance instead of its own class, for polymorphism
Suppose I have two related classes MyClass::A and MyClass::B that are both subclasses of MyClass. I would like the constructor for MyClass to take a filename, read the file, and based on the contents of the file, decide whether the file is of type A or B. Then, it should construct an object of the appropriate subclass and return it. Edit: Actually, it should call the constructor of the appropriate subclass and return the result.
So for example, after this code,
my $filename = "file_of_type_A.txt";
my $object = MyClass->new($filename);
$object
should be an instance of MyClass::A. This seems like valid behavior, because $object->isa('MyClass')
will always return true. I was thinking of using introspection to get a list of all subclasses of MyClass, and then trying to construct each in turn, until one succeeds. However, I don't see a way to modify the Moose constructor to do this. Neither the BUILDARGS nor BUILD hooks seem appropriate.开发者_JS百科
So how can I modify a Moose class's constructor to select an appropriate subclass and delegate construction to that subclass?
As Ether said above, you should have a factory method do this task. I like to put the factory method in a separate package/class from the things it produces Usually this is a virtual class that has no attributes or constructor, but if you want to do things like keep track of what you have made, you can create an actual factory object.
package MyFile::Factory;
sub make_file_object {
my $class = shift;
my $filepath = shift;
my $type = $class->determine_file_type( $filepath );
my $file_class = $class->get_class_for_file_type( $type );
return $file_class->new( $filepath, @_ );
}
# implement those other methods down here.
1;
精彩评论