Overriding a hard coded ISA module

Discussion in 'Perl Misc' started by xhoster@gmail.com, Feb 16, 2006.

  1. Guest

    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
    , Feb 16, 2006
    #1
    1. Advertising

  2. Anno Siegel Guest

    <> 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.
    Anno Siegel, Feb 16, 2006
    #2
    1. Advertising

  3. Anno Siegel Guest

    <> 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.
    Anno Siegel, Feb 16, 2006
    #3
  4. Ch Lamprecht Guest

    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//"
    Ch Lamprecht, Feb 16, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luis Esteban Valencia
    Replies:
    1
    Views:
    513
    Curt_C [MVP]
    Jan 6, 2005
  2. Luke Airig
    Replies:
    1
    Views:
    569
    Dimitre Novatchev
    Dec 24, 2003
  3. rodchar
    Replies:
    2
    Views:
    341
    rodchar
    Jul 1, 2008
  4. Aidan Gauland

    Refactoring hard-coded values

    Aidan Gauland, Jun 29, 2011, in forum: XML
    Replies:
    1
    Views:
    1,280
    Joe Kesselman
    Jun 30, 2011
  5. Microsoft

    How to avoid accessing row values with hard coded index

    Microsoft, Sep 24, 2003, in forum: ASP .Net Datagrid Control
    Replies:
    2
    Views:
    142
    Perecli Manole
    Oct 3, 2003
Loading...

Share This Page