perl5 icon indicating copy to clipboard operation
perl5 copied to clipboard

INIT processing in 5.6.0

Open p5pRT opened this issue 25 years ago • 10 comments

Migrated from rt.perl.org#2917 (status was 'open')

Searchable as RT2917$

p5pRT avatar Mar 31 '00 07:03 p5pRT

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

p5pRT avatar Mar 31 '00 07:03 p5pRT

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

p5pRT avatar Apr 01 '00 16:04 p5pRT

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

p5pRT avatar Apr 02 '00 04:04 p5pRT

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

p5pRT avatar Apr 02 '00 23:04 p5pRT

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

p5pRT avatar Oct 11 '00 08:10 p5pRT

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).

p5pRT avatar Aug 02 '08 09:08 p5pRT

@chorny - Status changed from 'open' to 'stalled'

p5pRT avatar Apr 13 '10 14:04 p5pRT

@cpansprout - Status changed from 'stalled' to 'open'

p5pRT avatar Apr 29 '11 03:04 p5pRT

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 #####

p5pRT avatar Aug 31 '13 01:08 p5pRT

Still present in 5.35.12

khwilliamson avatar Apr 23 '22 19:04 khwilliamson

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.

tonycoz avatar Apr 16 '25 05:04 tonycoz