Thanks for the input Stats.  I found your debugging methodology
to be very informative and especially useful in a mod_perl environment.

I tried your suggestion of commenting out
             require $key;
in Reload.pm, but it did not work for me.  I'd be happy to try
any other suggestions you might have.

Your code to work around Exporter worked fine.  However,
I think I'll stick with using Exporter so that I can make use
of the export tags.

Thanks again!

Ted


Stas Bekman wrote:

> Ted Prah wrote:
> > Hi again,
> >
> > I'm having trouble seeing module changes when I reload
> > a script that uses it.
>
> That's because Reload.pm doesn't re-exports the symbols when reloading
> the module and test.pl doesn't call import() because it sees the module
> in %INC, therefore it still sees the old sub till the moment it gets
> recompiled. Below you will find a complete analysis.
>
> > I'm using Apache::Reload and my test
> > script/module is as follows:
> >
> >
> > test.pl
> > --------------------
> > #!/usr/local/bin/perl
> > use strict;
> > use warnings;
> >
> > use My::Test qw(:subs);
> >
> > print "Content-type: text/plain\r\n\r\n";
> > &test1();
> > --------------------
> >
> >
> > Test.pm
> > --------------------
> > package My::Test;
> > use strict;
> > use warnings;
> >
> > BEGIN {
> >     use Exporter ();
> >
> >     our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
> >
> >     @ISA       = qw(Exporter);
> >     @EXPORT    = qw();
> >     @EXPORT_OK = qw();
> >
> >     %EXPORT_TAGS = (
> >                     subs => [qw(test1)],
> >                    );
> >
> >     Exporter::export_ok_tags('subs');
> >
> > }
> >
> > sub test1 { print "In test1 func\n"; }
> >
> > 1;
> > --------------------
>
> adjust the test.pl to do:
>
> test1(); print \&test1, "\n";
> #test2(); print \&test2, "\n";
>
> and My::Test.pm to:
>
> ...
> warn "test1:", \&test1, "\n";
> #warn "test2:", \&test2, "\n";
> sub test1 { print "In test1 func\n"; }
> #sub test2 { print "In test2 func\n"; }
> ...
>
> The first time you run the script you will see:
>
> output:
> In test1 func
> CODE(0x85ad38c)
>
> error_log:
> test1:CODE(0x85ad38c)
>
> you can see that both test1 and My::Test::test1 point to the same sub.
>
> > When I modify sub test1, and I reload - no changes appear
> > in the browser.  The following gets printed to error_log:
> > Subroutine test1 redefined at /export/home/httpd/cgi-bin/My/Test.pm line 22.
>
> output:
> In test1 func
> CODE(0x85ad38c)
>
> error_log:
> test1:CODE(0x84ee110)
>
> as you see the test1 is not the same as My::Test::test1
>
> > When I touch test.pl - the changes appear.  The following gets printed
> > to error_log:
> > Subroutine test1 redefined at /export/home/httpd/cgi-bin/My/test.pl line 5
>
> output:
> In test11 func
> CODE(0x84ee110)
>
> now it points to the recent My::Test::test1
>
> In that way you can debug any "mysteries" in Perl code.
>
> Now, how to solve this problem. For example comment out
>              require $key;
>
> in Reload.pm
>
> that way, test.pl will see that My::Test is not in %INC, and require it
> + call its import() method.
>
> Tell if this worked and we may adjust Reload.pm to have a special mode
> where it makes Perl forget about modified modules and let the code that
> loaded them in first place do the loading (and therefore the importing).
>
> > Finally, if I add a new subroutine test2 to Test.pm, export it, and
> > update the test.pl script to call test2, the script fails with an
> > Internal
> > Server Error.  The following gets printed to error_log:
> > "test2" is not exported by the My::Test module at
> > /export/home/httpd/cgi-bin/My/test.pl line 5
> > [Wed May 22 15:26:12 2002] [error] Can't continue after import errors at
> >
> > /export/home/httpd/cgi-bin/My/test.pl line 5
> > BEGIN failed--compilation aborted at /export/home/httpd/cgi-bin/
> > My/test.pl line 5.
> >
> > Then, when I restart the server, the script runs fine.
>
> Hmm, this one is different. Seems like a bug in Exporter.
>
> if you remove Reload.pm from the setup, so it won't confuse you and
> adjust the code to do:
>
> do "My/Test.pm";
> My::Test->import(':subs');
>
> you will see that it fails as well. This code acts like Reload.pm, but
> always reloads the module. So it's not Reload.pm's fault.
>
> Is anybody else  familiar with this Exporter's (mis)behavior?
>
> The solution that I see is to use something like this:
>
> package My::Test;
>
> use strict;
> use warnings;
>
> sub import {
>      my $package = shift;
>
>      no strict 'refs';
>      for (@_) {
>          *{ (caller)[0] . "::$_" } = \&{$_};
>      }
> }
>
> sub test1 { print "In test1 func\n"; }
> sub test2 { print "In test2 func\n"; }
>
> 1;
>
> If somebody else can see the problem with Exporter may be we need to run
> it through p5p.
>
> __________________________________________________________________
> Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
> http://stason.org/     mod_perl Guide ---> http://perl.apache.org
> mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
> http://modperlbook.org http://apache.org   http://ticketmaster.com



Reply via email to