Skip Menu |

This queue is for tickets about the Class-Load CPAN distribution.

Report information
The Basics
Id: 63013
Status: open
Priority: 0/
Queue: Class-Load

People
Owner: Nobody in particular
Requestors: KENTNL [...] cpan.org
tomas.zemres [...] gmail.com
Cc: ribasushi [...] leporine.io
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: False postive class_loaded despite module death
There's an annoying condition that arrises ( on all Perls so far :( )  that if a module manages to populate ISA before it dies, then it will appear to be a valid module.

And whats worse, is it trips our heuristics in both old and new perls!

https://github.com/kentfredric/class-load/compare/master...ISA_FalsePositive

Has 2 tests ( both for using 'die' and actual syntax errors, both cause the behaviour )

I'm not sure how to resolve this at present.

Stepping through with the debugger pointed me to this line returning true:

sub is_class_loaded {
...
    return 1 if exists ${$$pack}{ISA}
             && defined *{${$$pack}{ISA}}{ARRAY};


which results in

sub try_load_class {
...
   return 1 if is_class_loaded($class);

Fixed in 0.06. Thanks again Kent!
On 2010-11-27 09:18:36, SARTAK wrote:
Show quoted text
> Fixed in 0.06. Thanks again Kent!

How exactly is it fixed in 0.06? I thought it was 0.06 I filed the bug with, and based the patches relative to >_>.

Unless you mean 0.07, but that hasn't appeared on CPAN or in Github yet =P

On Mon Nov 15 19:52:32 2010, KENTNL wrote: Show quoted text
> There's an annoying condition that arrises ( on all Perls so far :( ) > that if a > module manages to populate ISA before it dies, then it will appear to > be a > valid module.
I just looked into this, and I'm not sure it's entirely fixable. In the case where module causes a syntax error, everything works as expected. I assume this happens because the syntax error happens at compile time, before @ISA is set at run time. If @ISA is set before the module dies (either in a BEGIN block or because of a runtime die) there's really no way to detect that. The only way I can think of to fix this is to maintain a black list of failed modules, but that makes everything more complex, because then we'd have to account for the module being changed on disk. Ugh.
Doh, I forgot mention that I did incorporate your tests into the distro, marking some of them as $TODO tests.
On Mon Sep 12 21:59:47 2011, DROLSKY wrote: Show quoted text
> If @ISA is set before the module dies (either in a BEGIN block or > because of a runtime die) there's really no way to detect that. > > The only way I can think of to fix this is to maintain a black list of > failed modules, but that makes everything more complex, because then > we'd have to account for the module being changed on disk. Ugh.
What about doing a Class::Unload pass if require dies? I can hardly imagine someone *relying* on being abl to find the parts of the symtable populated before require had a chance to die.
So any word on the Class::Unload idea?
On Mon Jul 08 01:30:07 2013, RIBASUSHI wrote: Show quoted text
> So any word on the Class::Unload idea?
On one hand, I like it. On the other, I worry that Perl doesn't _really_ support unloading a package, so who knows what sort of subtle problems using this could create.
CC: KENTNL [...] cpan.org
Subject: Re: [rt.cpan.org #63013] False postive class_loaded despite module death
Date: Tue, 9 Jul 2013 18:24:01 +0000
To: Dave Rolsky via RT <bug-Class-Load [...] rt.cpan.org>
From: Peter Rabbitson <ribasushi [...] cpan.org>
On Tue, Jul 09, 2013 at 11:15:59AM -0400, Dave Rolsky via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=63013 > > > On Mon Jul 08 01:30:07 2013, RIBASUSHI wrote:
> > So any word on the Class::Unload idea?
> > On one hand, I like it. On the other, I worry that Perl doesn't _really_ support unloading a package, so who knows what sort of subtle problems using this could create.
Perhaps this is enough reason to give it a try? We could do a devrel and kindly ask Andreas to run a cpan smoke with it (it takes about a week given his scheduling). Additionally this is low-level-enough dependency, and the problem scope is rather limited - thus I feel if there *are* issues with this they will pop out rather quickly. As usual I have no problem delivering an actual patch, but that's a minor detail relative to the design decision. Thoughts?
Subject: Re: [rt.cpan.org #63013] False postive class_loaded despite module death
Date: Tue, 9 Jul 2013 13:27:29 -0500 (CDT)
To: Peter Rabbitson via RT <bug-Class-Load [...] rt.cpan.org>
From: Dave Rolsky <autarch [...] urth.org>
On Tue, 9 Jul 2013, Peter Rabbitson via RT wrote: Show quoted text
> Perhaps this is enough reason to give it a try? We could do a devrel and > kindly ask Andreas to run a cpan smoke with it (it takes about a week > given his scheduling). > > Additionally this is low-level-enough dependency, and the problem scope > is rather limited - thus I feel if there *are* issues with this they > will pop out rather quickly.
This sounds like a good idea. -dave /*============================================================ http://VegGuide.org http://blog.urth.org Your guide to all that's veg House Absolute(ly Pointless) ============================================================*/
On 2011-09-12 18:59:47, DROLSKY wrote: Show quoted text
> On Mon Nov 15 19:52:32 2010, KENTNL wrote:
> > There's an annoying condition that arrises ( on all Perls so far :( ) > > that if a > > module manages to populate ISA before it dies, then it will appear to > > be a > > valid module.
> > I just looked into this, and I'm not sure it's entirely fixable. > > In the case where module causes a syntax error, everything works as > expected. I assume this happens because the syntax error happens at > compile time, before @ISA is set at run time. > > If @ISA is set before the module dies (either in a BEGIN block or > because of a runtime die) there's really no way to detect that. > > The only way I can think of to fix this is to maintain a black list of > failed modules, but that makes everything more complex, because then > we'd have to account for the module being changed on disk. Ugh.
23:21 < ether> I just got bitten by Class::Load::load_class 23:22 < ether> tried to load Foo inside an eval; Foo died. tried to load Foo again later, also in an eval, but load_class('Foo') returned true this time, so I went on to do something with the class and exploded 23:22 < ether> $INC{'Foo.pm'} existed, but was undef 23:23 < ether> it's not htat helpful if load_class('Foo') only dies the first time but pretends to work thereafter 23:28 < ether> this looks to be because Foo managed to define some symbols first before it croaked.. and _is_class_loaded takes a non-empty stash to mean that it's loaded 23:31 < ether> ...and then, later on when I try "do stuff" with the class, Module::Runtime::use_module is called on the class - and it correctly sees that the module isn't loaded, tries to load it, and so require() blows up with "Attempt to reload %s aborted." 23:32 < ether> and the perldiag explanation exactly sums up what happened - $INC{'Foo.pm'} existed but was empty, signalling a failed load attempt 23:32 < ether> so clearly _is_class_loaded ought to be doing the same 23:33 * ether sees kentnl already filed this - #63013 To summarize: this is the same problem as kentnl, but it is indeed fixable, because the %INC entry exists *but is not defined* (at least it is in my case). This is something we can actually check for.
Subject: Second load_class/try_load_class is successful even if class contain errors.
With following code: == TestClass1.pm (Tested class with referenced invalid package) == ------------------------- package TestClass1; use Moose; use InvalidPackage666; 1; ------------------------- == First test: test1.pl == ------------------------- use Class::Load 'try_load_class'; use FindBin; use lib "$FindBin::Bin"; print "first try: ",try_load_class('TestClass1'),"\n"; print "second try: ",try_load_class('TestClass1'),"\n"; print "third try: ",try_load_class('TestClass1'),"\n"; ------------------------- "first try" failed due to non-existing package "InvalidPackage666". but following calls "secods try" and "third try" returns True (it looks like package was successfully loaded). == Other test in test2.pl == ------------------------- use Class::Load 'load_class'; use FindBin; use lib "$FindBin::Bin"; eval { print "first try: ",load_class('TestClass1'),"\n"; }; eval { print "second try: ",load_class('TestClass1'),"\n"; }; ------------------------- there is printed "second try: TestClass1" so that it looks like TestClass1 is successfully loaded, but it isn't.