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

I have several methods that execute the same 2 lines of code at the beginning of their subs. These 2 lines check to see if the methods were called with arguments. If so, an error message is displayed. In other words, these methods don't accept arguments.

What can I do to reduce the repetition of writing those 2 lines for every method? Someone suggested that I use a module to handle the attributes of the methods, but I am hoping to do this without the help of a module.

Also, at the end of certain methods (about a dozen or so), I print some HTML. It is always the same HTML. I was hoping the I could use DESTROY as a means of tacking on that HTML to the method calls that need them. Would that be a good thing to do? Thanks Monks.

  • Comment on Controlling the start and endings of method calls

Replies are listed 'Best First'.
Re: Controlling the start and endings of method calls
by rhesa (Vicar) on Feb 02, 2006 at 00:43 UTC
    What you're looking for is something that for instance Hook::WrapSub provides. Other similar modules include Class::Hook, but there are many more. Searching on "Hook" gives you enough to get, err, dizzy ;)

    The documentation for Hook::WrapSub has some suggestions that apply directly to your requirements:

    use Hook::WrapSub qw( wrap_subs ); wrap_subs \&before, 'some_func', 'another_func', \&after; sub before { croak "No arguments allowed!" if @_; # but if you're wrapping object methods, you might want to take # the object reference (i.e. $self) into account: # croak "No arguments allowed" if @_ > 1; } sub after { print "Always the same <html>..."; } # your subs follow
Re: Controlling the start and endings of method calls
by davido (Cardinal) on Feb 02, 2006 at 01:41 UTC

    Well, you could reduce it to one line, and hide that line in another helper sub, I suppose. This method relies on the fact that if a sub is called with an '&' and without an explicit parameter list, it inherits @_ from its caller (see perlsub).

    use strict; use warnings; package TestClass; sub _has_params { return @_ > 1 ? scalar(@_) - 1 : 0; } sub mytest { die "@_\n" if &_has_params; print "We're ok.\n"; } 1; package main; print "Testing with no parameters.\n\t"; TestClass->mytest( ); print "Testing with one parameter.\n\t"; TestClass->mytest( "Hello" );

    There is one trick though, and I'm sure you're already dealing with it somehow: When a sub is called as a method (be it a class method or an object method) it will have one parameter passed into @_; either the class name or the self object ref. That's why in my "has_params()" subroutine, I only trigger a positive if there is more than one parameter.

    When you run the snippet above you'll see that it passes the first test, and dies on the second one.


    Dave

      sub _has_params { return @_ > 1 ? scalar(@_) - 1 : 0; }

      How 'bout

      sub _has_params { @_ - 1 }

      ?

      It would also check if it is called as a sub with no arguments... oh, well, and it wouldn't catch a call like a sub with exactly one argument...

        But then if the 'method' was invoked as a sub from within the class it could potentially have no params, leading to a return value of -1, which would give a false positive.


        Dave