![]() |
Overriding a hard coded ISA module
Is there an elegant way to tell other modules which are ISA some parent
(either directly or indirectly) that they should be ISA something else instead? For example, GD::Graph::lines, GD::Graph::points, and GD::Graph::linespoints.pm are all subclasses of GD::Graph::axestype. I want to subclass GD::Graph::axestype and override a method in it, and have that override exist for the three end-use modules. Currently the way I do it is to subclass each of the end-use modules individually: package Xho::linespoints; use base qw(GD::Graph::linespoints); ## GD::Graph is very buggy if numeric X axis are used ## without x_min_value and x_max_value being set. ## So set them to the pretty choice made by _best_ends sub setup_x_step_size_v { my $s=shift; if ( defined $s->{x_tick_number}) { $s->{x_min_value}=$s->{x_min} unless defined $s->{x_min_value}; $s->{x_max_value}=$s->{x_max} unless defined $s->{x_max_value}; }; $s->SUPER::setup_x_step_size_v; }; ## and likewise for other end-use modules. Doing it this way isn't too awful, but it seems like there should be a better way. Thanks, Xho -- -------------------- http://NewsReader.Com/ -------------------- Usenet Newsgroup Service $9.95/Month 30GB |
Re: Overriding a hard coded ISA module
<xhoster@gmail.com> wrote in comp.lang.perl.misc:
> Is there an elegant way to tell other modules which are ISA some parent > (either directly or indirectly) that they should be ISA something else > instead? Change their @ISA? > For example, GD::Graph::lines, GD::Graph::points, and > GD::Graph::linespoints.pm are all subclasses of GD::Graph::axestype. > > I want to subclass GD::Graph::axestype and override a method in it, and > have that override exist for the three end-use modules. Currently the way > I do it is to subclass each of the end-use modules individually: I'd try this (untested): Make your own less buggy Xho::axestype: package Xho::axestype; use base 'GD::Graph::axestype'; sub buggy_method { # your non-buggy override } 1; Then, before using GD::Graph, but after its @ISA is set up, do something like this: for ( \ ( GD::Graph::lines::ISA, GD::Graph::points::ISA, GD::Graph::linespoints::ISA, ) ) { $_ eq 'GD::Graph::linespoints' and $_ = 'Xho::linespoints' for @$_; } That should make the three modules use your improved version. The @ISA-modifying code could go in a CHECK- or INIT-block to make sure everything is loaded when it is called. Anno -- If you want to post a followup via groups.google.com, don't use the broken "Reply" link at the bottom of the article. Click on "show options" at the top of the article, then click on the "Reply" at the bottom of the article headers. |
Re: Overriding a hard coded ISA module
<xhoster@gmail.com> wrote in comp.lang.perl.misc:
> Is there an elegant way to tell other modules which are ISA some parent > (either directly or indirectly) that they should be ISA something else > instead? Change their @ISA? > For example, GD::Graph::lines, GD::Graph::points, and > GD::Graph::linespoints.pm are all subclasses of GD::Graph::axestype. > > I want to subclass GD::Graph::axestype and override a method in it, and > have that override exist for the three end-use modules. Currently the way > I do it is to subclass each of the end-use modules individually: I'd try this (untested): Make your own less buggy Xho::axestype: package Xho::axestype; use base 'GD::Graph::axestype'; sub buggy_method { # your non-buggy override } 1; Then, before using GD::Graph, but after its @ISA is set up, do something like this: for ( \ ( GD::Graph::lines::ISA, GD::Graph::points::ISA, GD::Graph::linespoints::ISA, ) ) { $_ eq 'GD::Graph::linespoints' and $_ = 'Xho::linespoints' for @$_; } That should make the three modules use your improved version. The @ISA-modifying code could go in a CHECK- or INIT-block to make sure[1] everything is set up when it is called. Anno [1] Well, make it likely that everything is set up. -- If you want to post a followup via groups.google.com, don't use the broken "Reply" link at the bottom of the article. Click on "show options" at the top of the article, then click on the "Reply" at the bottom of the article headers. -- If you want to post a followup via groups.google.com, don't use the broken "Reply" link at the bottom of the article. Click on "show options" at the top of the article, then click on the "Reply" at the bottom of the article headers. |
Re: Overriding a hard coded ISA module
xhoster@gmail.com wrote:
> For example, GD::Graph::lines, GD::Graph::points, and > GD::Graph::linespoints.pm are all subclasses of GD::Graph::axestype. > > I want to subclass GD::Graph::axestype and override a method in it, and > have that override exist for the three end-use modules. Currently the way > I do it is to subclass each of the end-use modules individually: > > package Xho::linespoints; > use base qw(GD::Graph::linespoints); > ## GD::Graph is very buggy if numeric X axis are used > ## without x_min_value and x_max_value being set. > ## So set them to the pretty choice made by _best_ends > sub setup_x_step_size_v { > my $s=shift; > if ( defined $s->{x_tick_number}) { > $s->{x_min_value}=$s->{x_min} unless defined $s->{x_min_value}; > $s->{x_max_value}=$s->{x_max} unless defined $s->{x_max_value}; > }; > $s->SUPER::setup_x_step_size_v; > }; Hi, I wrote a short example to find out how overriding of a method defined in a baseclass can be done using multiple inheritance. The code works, but I'm sure my approach to replace 'SUPER' is not the best one ... Any suggestions ?? Christoph use warnings; use strict; package Root; sub new{ my $class= shift; my $self = {}; return bless $self ,$class ; } sub hello{ print "Root->hello\n"; } sub say_hi{ print "Root->say_hi \n"; } package Root_patch; sub hello{ my $self = shift; print "Root_patch->hello\n"; if (my $coderef = $self->find_next('hello')){ $coderef->($self,@_) } } sub find_next{ # step through selfs @ISA and return the 1st method 'method_name' # found after the one defined in the current package my ($self,$method_name)= @_; my $class = ref $self; no strict 'refs'; my $get_this; for my $parent(@{$class."::ISA"}){ if ($parent eq __PACKAGE__){$get_this = 1; next;} if ($get_this && (my $code = $parent->can($method_name))){ return $code; } } return undef; } package Child; use base qw/Root_patch Root/; package main; my $instance = Child->new; $instance->hello; $instance->say_hi; __END__ output: Root_patch->hello Root->hello Root->say_hi -- perl -e "print scalar reverse q/ed.enilno@ergn.l.hc/" |
| All times are GMT. The time now is 06:54 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.