in reply to Re: Am I evil for doing this?
in thread Am I evil for doing this?

jdporter suggested: use strict; my $method = "rewrite_$2"; $_ = $self->$method($1) . "\n";
Actually, that seems slightly LESS evil to me...you are calling a method as a method, allowing Perl to Do The Right Thing in terms of argument passing and inheritance. I'm calling a method as a sub, and tricking it into working by explicitly passing the $self ref. Which means, of course, that your version is better code...just not better evil. :>

Replies are listed 'Best First'.
Re^3: Am I evil for doing this?
by Mugatu (Monk) on Mar 10, 2005 at 22:41 UTC
    Actually, that seems slightly LESS evil to me

    It's so much less evil, in fact, that it's actually allowed by strict. That should say a lot. Frankly, I think jdporter's method isn't evil at all. If you wanted to be extra careful, you could use UNIVERSAL::can to make sure the method exists before trying to call it:

    use strict; my $method = "rewrite_$2"; if ($self->can($method)) { $self->$method($1); } else { warn "$self does not have $method"; }

    Update: ihb++, I agree fully with Re^5: Am I evil for doing this?

      It's so much less evil, in fact, that it's actually allowed by strict.
      Yes; but there is considerable disagreement as to whether this ought to be the case. Some very respectable occupants of the Perl pantheon believe that it's an unnecessary and arbitrary loophole.
      If you wanted to be extra careful, you could use UNIVERSAL::can...

      That actually depends on what you want. If you want to allow the possibility that the method could get handled by AUTOLOAD, then you should not pre-test with UNIVERSAL::can.

      There's also an issue with how you call can. I figure, if you don't know whether the object can handle the $method, then you might not know if it's even an object; so to avoid the error potentially resulting when $self is not an object, I usually do the following, though unfortunately it isn't as pretty:

      if ( UNIVERSAL::can( $self, $method ) ) {

        if ( UNIVERSAL::can( $self, $method ) ) {

        That too, unfortunately, isn't good either, if an autoloading class properly overloads can. Imho, a class that uses AUTOLOAD also has the obligation to overload can accordingly. If it doesn't that class should be fixed, not mine, if that's an option.

        I prefer to do can checks like

        if (blessed($self) || ! ref($self) and my $code = $self->can($method)) + { $self->$code(...); }
        if I need to handle $self's that can't invoke methods.

        Update: Forgot to mention &blessed comes from Scalar::Util.

        ihb

        See perltoc if you don't know which perldoc to read!

      I prefer to not do the method-lookup twice and use the code reference returned by can:

      if (my $code = $self->can($method)) { $self->$code(...); }
      $self->$code(...) where $code is a subroutine reference is equivalent to $code->($self, ...); you can even do []->$code or undef()->$code if you want.

      ihb

      See perltoc if you don't know which perldoc to read!

      It's so much less evil, in fact, that it's actually allowed by strict.
      That's probably the most evil statement in this entire thread. It suggests that 'strict' is this omniscient, benign being that flawlessly decides what's good for you and what not.

      It's not. Sometimes disabling strict is the right thing to do (because it allows you to do something that isn't otherwise possible, or it allows you write easier to understand code). Pleasing 'use strict;' should not be a design goal. Of course using "use strict;" is usually a good idea.

        It suggests that 'strict' is this omniscient, benign being that flawlessly decides what's good for you and what not.

        That wasn't my intent. The things allowed and disallowed by strict are generally thought out and usually embody common sense. Of course, it is not the only way to fly, but it is usually a helpful guideline of what is a good idea and what is not.

Re^3: Am I evil for doing this?
by Joost (Canon) on Mar 10, 2005 at 21:50 UTC

      You're absolutely right, but I'm not worried. The corporate culture at this company is such that it will never happen. (Though, granted, I'm hoping to change things...just a couple of months ago, I convinced them to buy a development server. Now I just need to convince them to develop and test on it, instead of on the production machine.)

      That said, I don't actually want to be evil, so I did it jdporter's way.