mcdave has asked for the wisdom of the Perl Monks concerning the following question:

I happen to be struggling with Class::DBI and date formats, but that's not what my question is about. I'll use my existing code for the sake of concreteness, but it's actually a question about Perl classes. The short version of the question is "how can I refer to 'the method I'm overriding' from within a method declaration in a package?"

Before querying my database for anything, I need to set NLS_DATE_FORMAT. It's possible that someone else needed to use a different format, so I should set it myself before every call, and reset it (to be polite). Don't be too mean about what a bad idea this is (I should probably use triggers); it's just the example to show my point.

Empirically, I've found that the following does what I want:

package MyDateExperiment ; use base qw/Class::DBI/ ; use Class::DBI::Plugin::DateFormat::Oracle qw(0.01) ; my $NLS_DATE_FORMAT_CONVENTIONAL = 'YYYY-MM-DD HH24:MI:SS' ; # # connection stuff... # name the table... # field definitions... # sub create { my $class = shift ; my $oldFormat = $class->get_nls_date_format; $class->set_nls_date_format( $NLS_DATE_FORMAT_CONVENTIONAL ) ; my $ans = $class->SUPER::create( @_ ) ; $class->set_nls_date_format( $oldFormat ) ; return $ans ; } sub get { my $class = shift ; my $oldFormat = $class->get_nls_date_format; $class->set_nls_date_format( $NLS_DATE_FORMAT_CONVENTIONAL ) ; my $ans = $class->SUPER::get( @_ ) ; $class->set_nls_date_format( $oldFormat ) ; return $ans ; } sub set { my $class = shift ; my $oldFormat = $class->get_nls_date_format; $class->set_nls_date_format( $NLS_DATE_FORMAT_CONVENTIONAL ) ; my $ans = $class->SUPER::set( @_ ) ; $class->set_nls_date_format( $oldFormat ) ; return $ans ; }
Now, I'm "smart" enough to see that create, get, and set are pretty similar and I'd prefer to be lazy. So I poke around and decide that this is what I'd prefer:
foreach my $meth (qw/create get set/) { no strict qw/refs/ ; *{__PACKAGE__ . "::$meth"} = sub { my $class = shift ; my $oldFormat = $class->get_nls_date_format; $class->set_nls_date_format( $NLS_DATE_FORMAT_CONVENTIONAL ) ; my $ans = _good_lord_what_function( @_ ) ; ### ??? $class->set_nls_date_format( $oldFormat ) ; return $ans ; } }
This "works" in that it defines the methods and they get called properly, but it's two hours later and I've got no idea how to call the superclass's "$meth" method when all I know is the string "$meth". Things I've tried (paraphrasing, because I didn't keep good track of all the experiments) include: There were others. Each failed in its own way (some aren't even syntactic). Can someone tell me the way I should have done it?



Replies are listed 'Best First'.
Re: How to get a reference to a superclass method?
by runrig (Abbot) on Feb 10, 2012 at 17:39 UTC
    my $super_meth = "SUPER::$meth"; $class->$super_meth(@_);
      You're kidding, right??!!

      Of course, you're not kidding, because it works just fine. If someone could point me toward an explanation of why that works, I'd be very grateful.

      It seems that my "just type and hope Perl figures it out" approach was closest, but I couldn't get a permutation of $class->SUPER::$meth to compile.

      If crack is whack, then meth is death!
Re: How to get a reference to a superclass method?
by Anonymous Monk on Feb 10, 2012 at 17:40 UTC

    $ perl -e " package Foo; our $VERSION = 0; sub VERSION { my $ss = q/SU +PER::VERSION/; shift()->$ss; } die Foo->VERSION " 0 at -e line 1.

    So  my $super = "SUPER::$meth"; $self->$super(@args);