Updating my modules

Ovid on 2002-10-28T00:30:24

For various reasons, the book appears to be on hold right now. The publisher has decided to "rethink" the marketing strategy and I'm not sure what, if anything, I'm supposed to be writing. In the meantime, I grabbed all (three) of my modules from the CPAN and planned to update them with Test::More as a prerequisite. I was using old-style "prints" before and they're a pain (not too mention that I'm told such prints tend to break on VMS systems .. I don't know why).

Naturally, since I now try to harp about tests and the importance of doing tests first, I decided to ignore my own advice and make some long-needed changes in one of the modules. I wound up breaking the module so badly that I couldn't get my tests to run and realized I was better off starting from scratch. I threw away my work, re-extracted the distribution and decided that my first task was merely to update the tests -- nothing else. Then, a test for CGI::Safe started failing.

can_ok( $query, 'header' );

Huh? I don't get it. This is a subclass of CGI.pm so I'm positive that it has a header function (sometime you should try subclassing an OO module that masquerades as functional -- it's not fun). So I try this:

my $can = $query->can('header');
print $can->();

It worked perfectly, so the can_ok() function appears to be broken. I upgraded to the latest version of Test::More, but no love. I stepped through everything in the debugger and got to the following line:

eval { $proto->can($method) } || push @nok, $method;

$proto is the query object and method is 'header', but somehow, the eval failed and the method got pushed onto the @nok array. I was pretty tired and just stopped at that point, but clearly something really weird was going on. I'll send a bug report once I get a test case, or I'll not send one once my test case shows that I am smoking crack. I know I'm probably missing something obvious, but it was the end of a long, frustrating day and I threw in the towel.

Update: Whoops! I left out some info up there. Seems I had printed a header as a test prior to calling the 'can' method. The header function is AUTOLOADed causing the CGI::Safe::can method to fail. That makes tests a bit more interesting.


can_ok()

chromatic on 2002-10-28T01:47:40

Perhaps the failing test exposed a need to override UNIVERSAL::can()?

Re:can_ok()

Ovid on 2002-10-28T02:15:27

Can you give me some suggestions? In this case, CGI::header() is autoloaded. I could override UNIVERSAL::can() to try and call the method first to force the autoload, but what if the method has side effects? Regardless, I'll be calling it after the can_ok() function, so I think that's probably not a big deal, but I can see instances (e.g., with an autoloaded iterator), where this may not be optimal behavior. Offhand, I can't think of anything in CGI.pm where this would be a problem, though. Interesting food for thought.

Re:can_ok()

chromatic on 2002-10-28T16:31:54

The simplest thing that could possibly work is to make a list of autoloaded methods and stick them into a hash. That turns can() into a hash lookup. From there, you're a bit limited on the available refactorings... you don't have a lot of good options to modify CGI.pm. That doesn't mean you can't take the first step, though.