Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • That is a warning message generated by Test::MockObject (chromatic) about DateTime::Locale because when things fail weirdly, chromatic was sick of receiving bogus error reports and complaints about Test::MockObject when it was really the fault of the person using UNIVERSAL::can/isa as a function (which they shouldn't be).

    DateTime::Locale needs to call stuff as a method, not a function.
    • Err, take a look at that line:

      unless ( $real_class->can('new') )
      What exactly is wrong with that?
      • A shot in the dark, but is $real_class loaded when you make that call?

        Compare:

        $ foo->isa('UNIVERSAL') and print "yes\n"
        <nothing>

        to

        $ package foo;
        $ foo->isa('UNIVERSAL') and print "yes\n"
        yes

        I think U::can might get upset in this case... but who knows.

        Another possibility... didn't that line use can as a function in an older version of the module?  I can't get the warning to happen with the latest DateTime::Locale, but I could about a year ago.
        • Sorry, an addendum:

          $ use UNIVERSAL::can;
          $ UNIVERSAL->can('can') and print "can can\n";
          can can
          $ FOOBAR->can('can') or print "cannot can\n";
          Called UNIVERSAL::can() as a function, not a method at (eval 59) line 5
          cannot can
          $ package FOOBAR;
          $ FOOBAR->can('can') and print "now can can\n";
          now can can

          • Yep, that's the issue. In fact, the use of can is a way to check if the module has been loaded. It's quicker than blindly using require in every case, I think.
            • That's the problem then. Your heuristic for testing if a class exists fights with my heuristic for testing if a class exists. I suppose U::i/U::c could skim through the optree for a method or method_named opcode, but that's a lot more work.

              • Well, I think the problem is yours, since clearly I'm using UNIVERSAL::can as a method there, not a function, but your module is reporting that I'm using it as a function anyway.
              • I cannot reproduce the behavior on perl 5.8.6. But based on the description, there is a simpler solution. See whether the package can was called for is in the package tree. If it is not, then don't warn.

                In fact you already have the necessary logic in UNIVERSAL::can to figure out whether the package is in the symbol table. Therefore the following patch looks like it should fix the problem:


                --- /usr/lib/perl5/site_perl/5.8.6/UNIVERSAL/can.pm 2006-03-31 22:15:10.000000000 -0800
                +++ can.pm 2007-11-01
                • D'oh. Just use warnings and I can reproduce the behaviour. And yes, my patch fixed it.
            • You are relying on undocumented internal behaviour. At the very least I can find no documentation that a class that has not been fully defined yet does not have the methods that all classes should have. In fact I would prefer it if Perl had the opposite behaviour. What will you do if that behaviour changes someday?

              Furthermore pity the poor programmer who has to figure out your code. Do you always put comments on your uses of that idiom? If not, then will it make sense to someone else that you're checki
              • D'oh! You aren't relying on undocumented internal behaviour. You're checking for whether the class can call new, not whether it can call can!

                I'll just go hide in a corner then.
        • I had the same thought, so I updated my DateTime/DateTime::Locale to the latest before my rant...on my strawberry perl install and on my Ubuntu/OSX installs which are quite recent.