In Moose, how can I get a class constructor to return an instance of a subclass?

Possible duplicate:
How to get Moose to return an instance of a child class instead of its own class for polymorphism

Suppose I have two related classes, MyClass :: A and MyClass :: B, which are subclasses of MyClass. I would like the MyClass constructor to take the file name, read the file and based on the contents of the file, decide if the file is type A or B. Then it must build the object of the corresponding subclass and return it. Edit: Actually, it must call the constructor of the corresponding subclass and return the result.

So, for example, after this code

my $filename = "file_of_type_A.txt"; my $object = MyClass->new($filename); 

$object must be an instance of MyClass :: A. This seems to be the correct behavior because $object->isa('MyClass') will always return true. I thought of using introspection to get a list of all the MyClass subclasses, and then try to build them in turn until it works. However, I see no way to modify the Moose constructor to do this. Neither the BUILDARGS hooks nor the BUILD hooks seem suitable.

So, how can I modify the constructor of the Moose class to select the appropriate subclass and delegate the construction to this subclass?

+4
source share
1 answer

As the above ether said, you should have a factory way to accomplish this task. I like to use the factory method in a separate package / class from what it produces. This is usually a virtual class that has no attributes or constructors, but if you want to do things like keep track of what you have done, 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; 
+5
source

All Articles