perl5
perl5 copied to clipboard
INIT processing in 5.6.0
From [email protected]
Is this a bug, a bugfix or just a random change in behaviour?
I have a homebrew psh here that reads a .pshrc at startup. This latter contains a C<use Error> and Error.pm contains an INIT block.
All this is fine with 5.005_03, but I get the following with 5.6.0:
Too late to run INIT block at /usr/local/lib/perl5/site_perl/Horus/Error.pm line 217, <RC> line 30.
The module is loaded in the following context:
{ package PSH; no strict; use strict 'subs'; eval $_; die "$_: $@\n" if $@; }
Comments?
Pete Jordan
From @TimToady
Pete Jordan writes: : Is this a bug, a bugfix or just a random change in behaviour? : : I have a homebrew psh here that reads a .pshrc at startup. This latter : contains a C<use Error> and Error.pm contains an INIT block. : : All this is fine with 5.005_03, but I get the following with 5.6.0: : : Too late to run INIT block at : /usr/local/lib/perl5/site_perl/Horus/Error.pm line 217, <RC> line 30. : : The module is loaded in the following context: : : { : package PSH; : no strict; : use strict 'subs'; : eval $_; : die "$_: $@\n" if $@; : } : : Comments?
I suspect it's being needlessly restrictive. Seems to me the only constraint on INIT should be on how *early* it runs, not on how late it runs. Once the main compilation is deemed to be complete, Perl should act as if INIT and BEGIN are the same thing. That is, once you're running the interpreter on the main code (whether or not we used a code generator back end), a late INIT block should act no different from a late BEGIN block. Just run it the moment it's parsed. It should even be theoretically possible to run an INIT block from within an END block, I imagine.
In short, I think we should ignore the time-travel paradoxes, and try to do what the user intends when they say INIT, which is to prepare for something else to happen at runtime. Who cares if it didn't get into the "official" INIT queue in time? The right thing is to run the INIT block. Even if it's officially late, it's probably soon enough to do whatever the writer of the INIT block intended it to do.
However, (thinking down the road a bit here) if at runtime a late CHECK block is encountered, we should perhaps reset the flag that says compilation is complete, and assume we're going to checkpoint again and dump out more precompiled stuff. In that case, we should again treasure up our INIT blocks for later. In fact, they should probably be added to the previous list, since the next we restart, we probably want all the INIT blocks, not just the new ones.
Larry
From [Unknown Contact. See original ticket]
Larry Wall <larry@wall.org> writes:
I suspect it's being needlessly restrictive. Seems to me the only constraint on INIT should be on how *early* it runs, not on how late it runs. Once the main compilation is deemed to be complete, Perl should act as if INIT and BEGIN are the same thing. That is, once you're running the interpreter on the main code (whether or not we used a code generator back end), a late INIT block should act no different from a late BEGIN block. Just run it the moment it's parsed. It should even be theoretically possible to run an INIT block from within an END block, I imagine.
That would be my expectation if I came to this "cold" and seems like a reasonable way forward.
But just to record historical behaviour prior to 5.6.0's addition of the warning "late" INIT blocks where silently pushed onto never to be looked at queue - all the warning does it make that behaviour user-visible. (Tk has XS side INIT block and has to run same code in bootstrap too to work round the non-running of INIT in 5.005.)
In short, I think we should ignore the time-travel paradoxes, and try to do what the user intends when they say INIT, which is to prepare for something else to happen at runtime. Who cares if it didn't get into the "official" INIT queue in time? The right thing is to run the INIT block. Even if it's officially late, it's probably soon enough to do whatever the writer of the INIT block intended it to do.
There is a small chance that running it will cause problems for modules which relied on the bug. But I don't think it is a big worry, the B::* compiler being in the state it is (and its running of INIT and CHECK blocks being newish) means that there are probably not many INIT blocks about - and those of us that have them are relatively well informed.
However, (thinking down the road a bit here) if at runtime a late CHECK block is encountered, we should perhaps reset the flag that says compilation is complete, and assume we're going to checkpoint again and dump out more precompiled stuff. In that case, we should again treasure up our INIT blocks for later.
In fact, they should probably be added to the previous list, since the next we restart, we probably want all the INIT blocks, not just the new ones.
Larry
From [Unknown Contact. See original ticket]
Larry Wall <larry@wall.org> wrote:
I suspect it's being needlessly restrictive. Seems to me the only constraint on INIT should be on how *early* it runs, not on how late it runs. Once the main compilation is deemed to be complete, Perl should act as if INIT and BEGIN are the same thing. That is, once you're running the interpreter on the main code (whether or not we used a code generator back end), a late INIT block should act no different from a late BEGIN block. Just run it the moment it's parsed. It should even be theoretically possible to run an INIT block from within an END block, I imagine.
This sounds right to me - it seems unreasonable to prevent the loading of modules at runtime just because they presume to contain INIT blocks...
Pete at home
From [email protected]
Larry suggested the 'too late for INIT block' bahaviour was needlessly unhelpful [0]. I notice it hadn't been fixed as of 5.7.0 - has anyone the intention and/or the knowledge to fix this?
Hugo
[0] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-04/msg00081.html
From [email protected]
On Wed Oct 11 01:19:16 2000, hv@hugo.hybyte.com wrote:
Larry suggested the 'too late for INIT block' bahaviour was needlessly unhelpful [0]. I notice it hadn't been fixed as of 5.7.0 - has anyone the intention and/or the knowledge to fix this?
Hugo
[0] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000- 04/msg00081.html
The code in question basically is:
#!/usr/bin/perl -l
use strict; use warnings;
print "before init"; eval "INIT { print qq(in init); };"; print "after init";
__END__ before init Too late to run INIT block at (eval 1) line 1. after init
Still present in blead (5.11.0).
@chorny - Status changed from 'open' to 'stalled'
@cpansprout - Status changed from 'stalled' to 'open'
From @jkeenan
On Sat Aug 02 02:30:47 2008, animator wrote:
On Wed Oct 11 01:19:16 2000, hv@hugo.hybyte.com wrote:
Larry suggested the 'too late for INIT block' bahaviour was needlessly unhelpful [0]. I notice it hadn't been fixed as of 5.7.0 - has anyone the intention and/or the knowledge to fix this?
Hugo
[0] http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000- 04/msg00081.html
The code in question basically is:
#!/usr/bin/perl -l
use strict; use warnings;
print "before init"; eval "INIT { print qq(in init); };"; print "after init";
__END__ before init Too late to run INIT block at (eval 1) line 1. after init
Still present in blead (5.11.0).
And present with 'say' in 5.18.0 as well:
##### $ perl -w -E 'say "before init";eval "INIT { say qq(in init); };";say "after init";' before init Too late to run INIT block at (eval 1) line 1. after init #####
Still present in 5.35.12
Is this actually considered a bug?
We have workaround code that treats INIT like BEGIN iff used by Module::Install::DSL, even though in this ticket $Larry suggests that a late INIT should be treated BEGIN in all cases.
See S_process_special_blocks() in op.c for the gory details.