Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Swit
-BEGIN PGP SIGNED MESSAGE- Moin, On 15-Jan-02 Piers Cawley tried to scribble about: Michael G Schwern [EMAIL PROTECTED] writes: [Snip a lot] Let's see if I can come up with a simple counterexample that will show up the problem. #!perl my($compile_time, $start_time); BEGIN {$compile_time .= localtime(time)} # Later: print Compiled at $compile_time\n; print Started at $start_time\n; ... BEGIN {$start_time .= localtime(time)} __END__ How do you intend to distinguish between those two BEGIN blocks, one of which must be run at script compile time, the other of which must be run at (for want of a better description) INIT time? And neither of which can be run twice (hence the .=). The only thing that can make that distinction is a human being. The And how does the interpreter do this? Certainly not by prompting the user: Run BEGIN blocks (y/n)? [y] Just a silly question...;o) Cheers, Tels - -- perl -MDev::Bollocks -e'print Dev::Bollocks-rand(),\n' vitalistically unleash guinine experiences http://bloodgate.com/perl My current Perl projects PGP key available on http://bloodgate.com/tels.asc or via email -BEGIN PGP SIGNATURE- Version: 2.6.3i Charset: latin1 iQEVAwUBPERfw3cLPEOTuEwVAQGJowf/SRAo1g1moUNX39RhOryFM3s1Jm2Kyohn ZKyk36QGuPeWltUKIDiJBGpSNnDjBm/ObJRf/wf9SM6JWBUE30Qp5JhMd/sKTWmZ 9Ku2Ra4BgQGSEU4+gkSlQSFGjt6Qos6+gyrohOs8wAEAOhGRcLhAL6iRp7K6E5KJ iaQ75F46bkZmb9mvfoXM6qbYsI8gWLlnVwP0/dlzylxHEYRD6zFubcciE1LTIt/2 HxYgNEg6/J1x/BQBs1JqZgT2zIj7mOZPICzBiVZ4Fp/2F9yiPWyltES9BgW17kJm Tc80P7dAcTNKHqRVpAPDh+2WWZb/sKYBHIy8zdCKj0RH4JkKjltYgg== =OjqE -END PGP SIGNATURE-
Re: Compiled programs to keep BEGIN blocks?
On 2002.01.13 22:25 Michael G Schwern wrote: Why would this: BEGIN { push @INC, 'foo'; } put 'foo' into @INC twice if it were compiled? The compiled program should not be storing the post-BEGIN value of @INC, it should store the original value at startup. The compilation occurs at CHECK-time, that is, after 'foo' has been pushed into @INC.
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switchto make Test::Builder output even if $^C ( for B::C ))
Michael G Schwern [EMAIL PROTECTED] writes: On Sun, Jan 13, 2002 at 10:04:58PM +0100, Mattia Barbon wrote: $ bleadperl -MO=-qq,Deparse foo.plx sub BEGIN { print foo\n; } print bar\n; If B::Deparse can save BEGIN blocks, B::C can. I didn't mean that I can't write code to make B::C save BEGIN blocks ( it'd require 10 lines, probably ), I did mean that doing so would not be a god idea: _I am saving the state of the program after those blocks were ran_ and they will be run _another time_ at runtime, and this is not correct: ( for example use lib 'a'; would put 'a' into @INC twice, once ( correctly ) at compile time, and another time ( incorrectly ) at runtime ). In this case this is not harmful, but you get the idea. I don't understand. The compiled program should do exactly what the original program did. Anything else, as difficult as it may be, is a bug. Lots of programs and modules do important load-time checks and logic inside BEGIN blocks. Why would this: BEGIN { push @INC, 'foo'; } put 'foo' into @INC twice if it were compiled? The compiled program should not be storing the post-BEGIN value of @INC, it should store the original value at startup. Um... You're wrong. If you do need 'startup time' initialization then you should do it in an INIT block. If I may quote from the documentation: Once a BEGIN has run, it is immediately undeĀ fined and any code it used is returned to Perl's memory pool. This means you can't ever explicitly call a BEGIN. So, by the time that the compiler comes to generate its output, the BEGIN block as vanished, never to be seen again, which is as it should be. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Sun, Jan 13, 2002 at 10:04:58PM +0100, Mattia Barbon wrote: $ bleadperl -MO=-qq,Deparse foo.plx sub BEGIN { print foo\n; } print bar\n; If B::Deparse can save BEGIN blocks, B::C can. I didn't mean that I can't write code to make B::C save BEGIN blocks ( it'd require 10 lines, probably ), I did mean that doing so would not be a god idea: _I am saving the state of the program after those blocks were ran_ and they will be run _another time_ at runtime, and this is not correct: ( for example use lib 'a'; would put 'a' into @INC twice, once ( correctly ) at compile time, and another time ( incorrectly ) at runtime ). In this case this is not harmful, but you get the idea. I don't understand. The compiled program should do exactly what the original program did. Anything else, as difficult as it may be, is a bug. Lots of programs and modules do important load-time checks and logic inside BEGIN blocks. Why would this: BEGIN { push @INC, 'foo'; } put 'foo' into @INC twice if it were compiled? The compiled program should not be storing the post-BEGIN value of @INC, it should store the original value at startup. This isn't the way B::C ( I suspect B::Bytecode and B::CC work the same way ) works. It _by design_ saves the state _after_ the BEGIB blocks are run; the idea is to skip compilation time. Now, I know this is not going to always work, and the only ( always ) working solution I see ( and I'd like to be proved wrong here ), is something like B::Script ( which stores the source code of the program+modules in a single executable ). And yes, I realized that [ B::C is not always going to work ] just a coule days ago. Regards Mattia
Re: Compiled programs to keep BEGIN blocks?
On Mon, Jan 14, 2002 at 11:13:27AM +0100, Rafael Garcia-Suarez wrote: On 2002.01.13 22:25 Michael G Schwern wrote: Why would this: BEGIN { push @INC, 'foo'; } put 'foo' into @INC twice if it were compiled? The compiled program should not be storing the post-BEGIN value of @INC, it should store the original value at startup. The compilation occurs at CHECK-time, that is, after 'foo' has been pushed into @INC. I don't know if this is true, but it isn't relevent. Remember, BEGIN, INIT, CHECK, etc... time is only relevent to the current module being loaded/run. As this example shows, Bar.pm's code is run before even Foo.pm's BEGIN block. Replace -MBar with -MO=C and you get the idea. # ~/tmp/Foo.pm package Foo; BEGIN { push @INC, 'foo'; } print \@INC as Foo has modified it\n; print join \n, @INC; # ~/tmp/Bar.pm package Bar; print \@INC as Bar sees it\n; print join \n, @INC; $ bleadperl -I/home/schwern/tmp -MBar -wle 'use Foo' @INC as Bar sees it /home/schwern/tmp /usr/local/bleadperl/lib/5.7.2/ppc-linux-64int /usr/local/bleadperl/lib/5.7.2 /usr/local/bleadperl/lib/site_perl/5.7.2/ppc-linux-64int /usr/local/bleadperl/lib/site_perl/5.7.2 /usr/local/bleadperl/lib/site_perl .. @INC as Foo has modified it /home/schwern/tmp /usr/local/bleadperl/lib/5.7.2/ppc-linux-64int /usr/local/bleadperl/lib/5.7.2 /usr/local/bleadperl/lib/site_perl/5.7.2/ppc-linux-64int /usr/local/bleadperl/lib/site_perl/5.7.2 /usr/local/bleadperl/lib/site_perl .. foo -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One We're talkin' to you, weaselnuts. http://www.goats.com/archive/000831.html
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switchto make Test::Builder output even if $^C ( for B::C ))
Michael G Schwern [EMAIL PROTECTED] writes: On Mon, Jan 14, 2002 at 10:23:46AM +, Piers Cawley wrote: Um... You're wrong. If you do need 'startup time' initialization then you should do it in an INIT block. If I may quote from the documentation: Like it or not, people put lots of init code into BEGIN blocks, if nothing else for backwards compatiblity with 5.005. perlcc has to compile real world programs. Deferring BEGIN blocks 'til runtime will break rather more realworld program than it fixes I think. Can't solve this with a do not rule. Once a BEGIN has run, it is immediately unde? fined and any code it used is returned to Perl's memory pool. This means you can't ever explicitly call a BEGIN. So, by the time that the compiler comes to generate its output, the BEGIN block as vanished, never to be seen again, which is as it should be. There's a special B::save_BEGINs function which O.pm uses to get around this. Like I said, if B::Deparse can do it, B::C can. But it shouldn't. How do you distinguish between: use Foo; (needs to use 'Foo' before generating the compiled script, otherwise what's the bloody point?) and BEGIN { ... } Also, as the docs for B::Deparse points out: we can't guarantee to produce BEGIN blocks or use declarations in exactly the right place. Which can become a big problem when you find that your compiled script doesn't work and there's no easy way of debugging the program that it thinks it's evaluating. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Mon, Jan 14, 2002 at 04:16:49PM +, Piers Cawley wrote: Michael G Schwern [EMAIL PROTECTED] writes: On Mon, Jan 14, 2002 at 10:23:46AM +, Piers Cawley wrote: Um... You're wrong. If you do need 'startup time' initialization then you should do it in an INIT block. If I may quote from the documentation: Like it or not, people put lots of init code into BEGIN blocks, if nothing else for backwards compatiblity with 5.005. perlcc has to compile real world programs. Deferring BEGIN blocks 'til runtime will break rather more realworld program than it fixes I think. Where is deferring involved? -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Lord of Kwalitee! Wearer of the CPANTS and Slayer of Pseudo-hashes!
Re: Compiled programs to keep BEGIN blocks?
On Mon, Jan 14, 2002 at 06:45:05PM +0100, Rafael Garcia-Suarez wrote: # ~/tmp/Bar.pm package Bar; print \@INC as Bar sees it\n; print join \n, @INC; Nah. You should wrap this code in a CHECK block : otherwise, in your example, it will be run at BEGIN-time (i.e. when the Bar module is use'd). That's what O.pm does. You forget (and I forgot), B::C is encased in the perlcc wrapper script. So what we really have is this: print \@INC as perlcc sees it\n; print join \n, @INC; system(qq{$^X -cwle 'BEGIN { push \@INC, bar }'}); So perlcc can simply save the state of @INC (and whatever else B::C might have trouble getting at) and pass that information along. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Maybe they hooked you up with one of those ass-making magazines. -- brian d. foy as misheard by Michael G Schwern
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On 2002.01.14 22:27 Michael G Schwern wrote: B::Deparse has slowly gotten very good at figuring out BEGIN blocks from 'use' statements and putting them in the right places. Hard fought knowledge. Steal from it. There are still problems with pragmas. (As I was working on B::Deparse the last few weeks, if you find new solutions, let me know.) I don't expect perlcc to magically become perfect overnight. What I do expect is that the 'compiled programs won't run code in BEGIN blocks' be treated as a bug and not a feature and to look around at other bits of B which are taking a stab at solving these problems.