in reply to Extending a class
Hi betacentauri,
In sub Bar, you're calling $g->Foo, where $g is the return value of $self->group. Looking at the code of SVG::Element, that's a new SVG::Element. SVG::Element doesn't have a sub Foo, which is why the call fails.
As suggested by the AM, one solution is to patch the methods into SVG::Element by defining them as sub SVG::Element::Foo { ... }, MyPackage isn't necessary in that case. (Note however that a new constructor for MyPackage is not required, as the AM seems to be saying; the constructor is indeed inherited from SVG, which in turn calls its parent constructor in SVG::Element, but since they are coded appropriately they give you an object of type MyPackage.) It's kind of inelegant but it works. If you're only adding a few methods, it might be an acceptable solution.
Other than that, since SVG::Element::tag() is hardcoded to return a new object of type SVG::Element, I can't at the moment think of a solution that doesn't involve either updating the SVG package itself, or some kind of inelegant hacking/patching (perhaps another monk has another alternative handy).
Update: You can also fix the immediate problem by writing return $g->MyPackage::Foo("g$barArg"); in Bar. This doesn't stop Foo and Bar from returning objects of type SVG::Element, but at least it gets your example code working... now I'm out of ideas for tonight. (I also tried reblessing the return values, but that caused the SVG to be missing elements, which I haven't looked into yet.)
Update 2: SVG::Element uses the code if ( ref($k) =~ /^SVG::Element/ ) (instead of isa) to check whether objects are of its type. I'd say this and the above make it too difficult to do normal subclassing.
Hope this helps,
-- Hauke D
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Extending a class (updated)
by betacentauri (Sexton) on Apr 13, 2016 at 21:59 UTC | |
by Athanasius (Archbishop) on Apr 14, 2016 at 08:00 UTC | |
by haukex (Archbishop) on Apr 13, 2016 at 22:54 UTC |