misleading error message from from_object?
[email protected] (Edward Baudrez)
| Newsgroups | perl.datetime |
|---|---|
| Message-ID | <[email protected]> |
Hi list I've stumbled upon (what I think is) a misleading error message from from_object(). Basically, the following code my $now = DateTime->now; my $copy = DateTime->from_object( $now ); should tell me I've omitted the mandatory 'object =>' key (as the docs state, so definitely my bad). However, the error message was confusing: The following parameter was passed in the call to DateTime::from_object but was not listed in the validation options: local_rd_secs It seems I'm not the only person who's confused (e.g., http://code.google.com/p/panchanga/issues/detail?id=1 and a few more). I've tried tracing the problem, but I admit it's beyond my comprehension. I vaguely suspect the overloading, because DateTime->from_object( $whatever ) --with $whatever being anything else than a DateTime object-- fails as it should, but I have no proof whatsoever. I'm attaching a test script that exposes the behaviour, and an (ugly?) workaround. Useful? Best regards Edward Baudrez -- Royal Meteorological Institute of Belgium Remote Sensing from Space Ringlaan 3, 1180 Ukkel, Belgium +32 2 373 0623 [email protected]
from_object.t
(text/troff, 2.2 KB)
use strict;
use warnings;
use Test::More;
use Test::Exception;
use DateTime;
use Carp qw( longmess confess );
# BACKGROUND
# this is the right way to call DateTime->from_object() (from the docs): the 'object' key is mandatory
my $now = DateTime->now;
ok $now;
my $copy = DateTime->from_object( object => $now );
ok $copy;
# calling DateTime->from_object() without 'object' dies:
throws_ok { DateTime->from_object( {} ) } qr/^Mandatory parameter 'object' missing in call to DateTime::from_object$/m;
# however, the following two die with an error message that is less explicit:
throws_ok { DateTime->from_object( 1 ) } qr/^Odd number of parameters in call to DateTime::from_object when named parameters were expected$/m;
throws_ok { DateTime->from_object( [] ) } qr/^Odd number of parameters in call to DateTime::from_object when named parameters were expected$/m;
# and this gives a misleading error message:
throws_ok { DateTime->from_object( $now ) }
qr/^(Mandatory parameter 'object' missing in call to DateTime::from_object|Odd number of parameters in call to DateTime::from_object when named parameters were expected)$/m;
# fails instead with
# 'The following parameter was passed in the call to DateTime::from_object but was not listed in the validation options: local_rd_secs'
# INVESTIGATION
# inspecting the arguments that validate() receives (set $show_args = 1 below)
# shows that validate() receives the object as the only argument, but somehow
# fails to notice the absence of the 'object' key
*real_validate = \&DateTime::validate;
my $show_args = 0;
if( $show_args ) {
no warnings 'redefine';
local *DateTime::validate = sub (\@$) {
note longmess '- CALLING validate()';
note "\$_[$_] = ", explain $_[ $_ ] for 0 .. $#_;
&real_validate
};
eval { DateTime->from_object( $now ) };
}
# POSSIBLE WORKAROUND
*real_from_object = \&DateTime::from_object;
{
no warnings 'redefine';
local *DateTime::from_object = sub {
my $class = shift;
confess( "Mandatory parameter 'object' missing in call to " . (caller 0)[3] . "\n" ) unless grep /^object$/, @_;
real_from_object( $class, @_ );
};
throws_ok { DateTime->from_object( $now ) } qr/^Mandatory parameter 'object' missing in call to /;
}
done_testing;