Skip Menu |

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

Report information
The Basics
Id: 71538
Status: rejected
Priority: 0/
Queue: Class-Load

People
Owner: Nobody in particular
Requestors: cjfields [...] uiuc.edu
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.11
Fixed in: (no value)



Attached are two files, a very simple module and one script. This is a minimal test example where we dynamically load a module and attempt to monkey-patch a new method to the loaded module's namespace (IMHO not a great practice, and I would consider this an edge case). Tests pass when wrapping the testing code in a BEGIN block or defining the class within the script (and of course NOT monkey-patching works as well). This works fine when using Module::Load::load() instead of Class::Load. Just from the test example, it appears the loaded module code is somehow wiped out. cjfields@pyrimidine:~/tests/classload$ perl class_load.pl ok 1 not ok 2 # Failed test at class_load.pl line 24. # died: Can't locate object method "new" via package "Foo" at class_load.pl line 24. not ok 3 - The thing isa Foo # Failed test 'The thing isa Foo' # at class_load.pl line 25. # The thing isn't defined 1..3 # Looks like you failed 2 tests of 3. cjfields@pyrimidine:~/research/Robinson/v4_5$ perl -v This is perl 5, version 14, subversion 0 (v5.14.0) built for x86_64- linux ... cjfields@pyrimidine:~/research/Robinson/v4_5$ uname -a Linux pyrimidine 2.6.32-34-generic #77-Ubuntu SMP Tue Sep 13 19:39:17 UTC 2011 x86_64 GNU/Linux
Subject: class_load.pl
#!/usr/bin/perl -w use Modern::Perl; use Test::Most; use Class::Load ':all'; # Tests fail as is. Three instances where tests pass: ############################################ # (1) class is defined locally (uncomment): #{ # package Foo; # sub new {return bless {}, shift} #} ############################################ # (2) ...or, enclosing code below in BEGIN block: #BEGIN { ok(try_load_class('Foo')); my $instance; lives_ok {$instance = Foo->new()}; isa_ok $instance, 'Foo'; #} ############################################ # (3) or, commenting this block out (no post-load modification of module code) { sub Foo::test { my $self = shift; return 'test'; } } done_testing();
Subject: Foo.pm
package Foo; use strict; use warnings; sub new { my $c = shift; return bless {}, $c; } 1;
Subject: Modification of modules after successful load_class() fails
From: cjfields [...] uiuc.edu
D'oh, forgot to add the subject line. Maybe 'Modification of modules after successful load_class() fails' or somesuch On Fri Oct 07 17:52:23 2011, cjfields wrote: Show quoted text
> Attached are two files, a very simple module and one script. > > This is a minimal test example where we dynamically load a module and > attempt to monkey-patch a new method to the loaded module's namespace > (IMHO not a great practice, and I would consider this an edge case). > Tests pass when wrapping the testing code in a BEGIN block or defining > the class within the script (and of course NOT monkey-patching works as > well). This works fine when using Module::Load::load() instead of > Class::Load. > > Just from the test example, it appears the loaded module code is somehow > wiped out. > > cjfields@pyrimidine:~/tests/classload$ perl class_load.pl > ok 1 > not ok 2 > # Failed test at class_load.pl line 24. > # died: Can't locate object method "new" via package "Foo" at > class_load.pl line 24. > not ok 3 - The thing isa Foo > # Failed test 'The thing isa Foo' > # at class_load.pl line 25. > # The thing isn't defined > 1..3 > # Looks like you failed 2 tests of 3. > > cjfields@pyrimidine:~/research/Robinson/v4_5$ perl -v > > This is perl 5, version 14, subversion 0 (v5.14.0) built for x86_64- > linux > ... > cjfields@pyrimidine:~/research/Robinson/v4_5$ uname -a > Linux pyrimidine 2.6.32-34-generic #77-Ubuntu SMP Tue Sep 13 19:39:17 > UTC 2011 x86_64 GNU/Linux
On Fri Oct 07 17:52:23 2011, cjfields wrote: Show quoted text
> Attached are two files, a very simple module and one script. > > This is a minimal test example where we dynamically load a module and > attempt to monkey-patch a new method to the loaded module's namespace > (IMHO not a great practice, and I would consider this an edge case). > Tests pass when wrapping the testing code in a BEGIN block or defining > the class within the script (and of course NOT monkey-patching works as > well). This works fine when using Module::Load::load() instead of > Class::Load.
The problem is that Class::Load will not attempt to load a class if it thinks that class is already loaded. Your sub definition happens at compile time, so Class::Load sees the sub when you ask it to load the Foo class. It concludes that Foo is already loaded. I don't think this is a bug, Class::Load is doing what it is documented to do. You can work around this by making the monkey patch a runtime event. You can either eval some code: eval "sub Foo::test { ... }" or you can assign to a glob: *Foo::test = sub { ... }; There's probably other ways to do this too. I'm marking this ticket rejected. Please don't respond directly to this email or the ticket will be reopened. Thanks, -dave