in reply to Strange bug involving mysql, auto_increment, Class::DBI and Test::MockObject

From the Test::MockObject ChangeLog file:

- use UNIVERSAL::isa and UNIVERSAL::can modules
These two module override &UNIVERAL::isa and &UNIVERSAL::can (obviously), and attempt to enforce their "proper" usage (called as a method, not as a function). Of course this is a subject not everyone agrees upon (just look at the CPAN reviews for the two UNIVERSAL:: modules to see this).

From your error messages, I can deduce that Class::DBI does not use &UNIVERSAL::can "properly", so that is the source of your error. Althougth the two errors that it is sandwiched between are (I suspect) bugs in UNIVERSAL::can since it really should handle those edge cases correctly.

UPDATE
Upon closer inspection of the issue, I found this at line 265 of Class::DBI:

line 255 > my @pk_values = $self->_attrs($self->primary_columns); line 265 > UNIVERSAL::can($_ => 'id') and $_ = $_->id for @pk_values;
Then given one of your fixes:
Hardcode the primary key value when you 'create' (i.e. set 'test1' to something)
I would suspect that this is possibly a bug in Class::DBI and maybe line 265 should read:
UNIVERSAL::can($_ => 'id') and $_ = $_->id for grep { defined $_ } @pk +_values;
Or something similar.

However, it could also be argued that it worked before, and the "bug" is only introduced by the addition of UNIVERSAL::can. So I guess it all comes down to which author you want to complain to, chromatic or TBOWDEN :)

-stvn

Replies are listed 'Best First'.
Re^2: Strange bug involving mysql, auto_increment, Class::DBI and Test::MockObject
by chromatic (Archbishop) on Dec 13, 2005 at 22:20 UTC

    Any code that uses UNIVERSAL::can() or UNIVERSAL::isa() as functions breaks Test::MockObject and Class::Roles. I can't fix that.

    I can use UNIVERSAL::isa and UNIVERSAL::can in my code to warn people that things will break if they use them incorrectly and to try to route around the damage as much as possible.

    Still, I don't have any sympathy for people who write broken code and expect it to work. If you break my code, you get to keep both pieces. Don't save your receipt.

    Oh, and the Class::DBI code should likely be instead:

    eval { $_->can( 'id' ) } and $_ = $_->id for grep { defined $_ } @pk_values;
      I can use UNIVERSAL::isa and UNIVERSAL::can in my code to warn people that things will break if they use them incorrectly and to try to route around the damage as much as possible.

      I agree with you 100%, however, the problem is that UNIVERSAL::can actually dies, and not just warns in this particular case. The last error in the OPs post ...

      Can't call method "can" on an undefined value at /usr/local/share/perl/5.8.4/UNIVERSAL/can.pm line 40.
      is actually UNIVERSAL::can die-ing. This is is something too that (IMO) can be routed around fairly easily so I sent you a patch and test for this.

      -stvn