Long Friday

Ovid on 2003-09-26T23:25:49

My goodness, it's been a long day. I spent an hour tracking down a bug caused by the following code.

my @methods = qw/follow_link get title/;

use Class::MethodMaker
    new    => 'new',
    object => [
        'WWW::Mechanize' => {
            slot       => 'browser',
            comp_mthds => [@methods],
        }
    ];

If it doesn't just jump out at you, you'll slap yourself when you find it.


Oops

pdcawley on 2003-09-27T19:49:56

Did sir forget his underscore?

And, out of interest, do you use @methods anywhere else? Looks like a useless use of variable to me. [qw/.../] is perfectly fine...

Re:Oops

Ovid on 2003-09-27T20:48:46

Oh goody. You're going to slap yourself :)

The first thing you do is create a file named "Foo.pm":

package Foo;

sub import { print "@_" }

1;

Then, in the same directory, run the following script:

#!/usr/local/bin/perl -w
use strict;

BEGIN { unshift @INC => '.' }
my @methods = qw/bar baz/;
use Foo @methods;

That prints "Foo". Foo's import method gets called with no arguments because the assignment to @methods happens after the use statement, even though strict does not complain because @methods has already been declared.

The reason I encountered this is because I had a class that was acting strangely so I was testing the interface. Thus, I had @methods declared so I could later iterate over it and check $object->can($method);.

Re:Oops

petdance on 2003-09-27T23:30:44

I think that if you do a
use constant METHODS => qw( foo bar bat );
then you can pass 'em in like you want.

Re:Oops

bart on 2003-09-28T21:58:33

Assign to @methods in a BEGIN block.
my @methods;
BEGIN { @methods =  qw/follow_link get title/; }

Re:Oops

pdcawley on 2003-10-02T11:48:57

You're right, I'm slapping myself. Iff need to use @methods anywhere else in your code.