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? (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? (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.
Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C )
On Sun, Jan 13, 2002 at 07:39:52PM +0100, Mattia Barbon wrote: perlcc seems to be dropping BEGIN blocks entirely, that's the problem. No, that's correct. Explanation: if I have a module Foo package Foo; $x = 1; print AAA; sub a { $x } 1; and a main program foo.pl BEGIN { # think use Foo;, expanded for clarity require Foo; } print Foo::a(); perl -MO=C foo.pl calls B::C::compile _after_ it ran the BEGIN blocks; this means that the optree in Foo that initializes $x, and does print AAA has already been freed. So, even if B::C could save BEGIN blocks, this is not a good idea, for quite a lot of reasons. I didn't write what I meant, sorry, see below $ 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. Regards Mattia
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. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Me? A robot? That's rediculous! For one thing, that doesn't compute at all!
Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C )
On Tue, Jan 08, 2002 at 11:02:27PM +0100, Mattia Barbon wrote: Code inside the BEGIN blocks has $^C set?? Or are they just not being run at all? Either of those are bugs. But there's a third The code inside the begin blocks has $^C set ( as it should ), and they are being run ( as they should ) The code inside the BEGIN blocks has $^C set *only when compiling with perlcc* right? If you run the bytecompiled code the BEGIN blocks should not have $^C set. Lemme recompile things and try this out. If you were to take: BEGIN { print foo } compile it and run it, would you expect the output to be 'foo'? Or is the problem that you're getting 'foo' both during the compilation *and* when its run? As with this: I'd expect the output of the compiled program to be nothing _normally_ ( perlcc foo.pl ), and foo _if I used the --testsuite switch when calling perlcc_ ( perlcc --testsuite foo.pl ). And in order to not have to introduce hacks in t/TEST, I'd like that the compiled program resulting from use Test::Simple tests = 12; would print nothing normally, and 1..2 _if I passed the --testsuite switch to perlcc_ . Now wait a second. Why would the compiled program print nothing normally? $^C should not be set. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Instant Cross-Platform CGI Programming in Visual Perl 5 with Object Oriented Design in 7 Days Unleashed for Dummies Special Edition with Exclusive Java Chapters for Developers. Year 2000 compliant, Enterprise edition and ISO9000- certified. A Nutshell Handbook Designed For Windows 95/98/NT with a forward by Larry Bud Melman. Interactive Multimedia CDROM included. 3rd revised editon, covers Perl5.6. Of course, it will be refered to by its simple acronym: ICPCGIPiVP5wOODi7DU4DSEwEJC4DY2KCEedISO9000-cNHD4W9598NTLBMIMCDROM3edP5.6
Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C )
On Sat, Jan 05, 2002 at 10:17:34PM +0100, Mattia Barbon wrote: On Wed, Jan 02, 2002 at 05:37:28PM +0100, Mattia Barbon wrote: I don't care for the variable name, but I'd really like to have this feature. Would it work ok as a Test::Builder accessor method rather than an environment variable? No, unfortunately, because the call order is like this: * init code in the backend * BEGIN blocks of the program ( including use Foo; ) * B::Backend::compile * the coderef returned by B::Backend::compile So I can't call the method from the init code in the backend, because Test::Builder hasn't been loaded yet, and calling it from the ::compile is too late ( output is already lost ); the alternative I see is to use a package variable; so I can set $Test::Builder::i_want_the_output_even_if_dollar_caret_C_is_1 = 1; in initialization code. You could do this: require Test::Builder; my $tb = Test::Builder-new; $tb-output_even_if_compiling(1); in the init code. Since Test::Builder is a singleton your settings should stick. Yes, but then B::C sees the Test::Builder stashes and saves them, for every compiled program. I might enable yhat based on some option/environment variable, but this just shifts the problem. Here's an interesting alternative. Do Clocal $^C = 0 just before running the tests, though that's pretty ugly. But I rwally like the environment variable better, because with the package variable solution I need to set it unconditionally ( because for it to have effect it must be set in the init code, and in the init code I can't look at parameters, because parameters are passed in the call to compile, so I can't set it using a parameter ), and because I was hoping to keep B::C clear from hacks-to-make-the-testsuite-happy. From my PoV, I'm hoping to keep Test::Builder clear from hacks-to-make-perlcc-happy. :) The $^C thing is already a hack for I knew you was going to say that :) B::Deparse. Could you explain again why you need test output while compiling, I'm not quite following. Assume you had the I_WANT_OUTPUT_DURING_COMPILE environment variable could you show how you'd be using it? Let's say I have this lib/Bar/t/bar.t ( not usint Test::* ) #!perl BEGIN { print 1..2\n }; BEGIN { print ok 1 }; print ok 2\n; This prints 1..2\nok 1\n at compile time, and ok 2\n; at run time. When compiled with perlcc --testsuite bar.t, perlcc saves the compile-time output, and passes to B::C the -eprint qq{1..2\nok 1\n} option ( -efoo means eval foo just before you run the program ); so the compiled program prints 1..2 ok 1 ok 2 and t/TEST is happy However lib/Foo/t/foo.t uses Test::Simple #!perl use Test::Simple tests = 2; BEGIN { use_ok('Foo') } ok( foo(1), foo(1) is true ); So when compiled with B::C, $^C is set, and it does not print the 1..2\nok 1\n at all, so perlcc does not see it, does not pass anything to B::C, so the compiled program prints just ok 2 and t/TEST is very unhappy. The I_WANT_BEGIN_OUT ( or whatever ) works around that. Hope it is clearer now. I could modify t/TEST, but I wanted to modify it as few as possible, and there really is no ( portable ) way to distinguish between a test that fails in the middle for some reason ( say it segfaults at test 7 ) and one that has just planned 6 tests. Regards Mattia
Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C )
On 2002.01.05 23:45 Michael G Schwern wrote: Here's an interesting alternative. Do Clocal $^C = 0 just before running the tests, though that's pretty ugly. Interesting idiom, but I don't see when this can be done. But I rwally like the environment variable better, because with the package variable solution I need to set it unconditionally ( because for it to have effect it must be set in the init code, and in the init code I can't look at parameters, because parameters are passed in the call to compile, so I can't set it using a parameter ), and because I was hoping to keep B::C clear from hacks-to-make-the-testsuite-happy. From my PoV, I'm hoping to keep Test::Builder clear from hacks-to-make-perlcc-happy. :) The $^C thing is already a hack for B::Deparse. Instead of using an environment variable, you can use a global variable in the O namespace. Let's say $O::No_Test_Output defaults to 1 (set by O.pm). In Test::Builder (line #571) you would have return if $O::No_Test_Output; # Don't print headers under compiler backends instead of return if $^C; and B::C (and other backends that want to behave this way) could override this setting by doing $O::No_Test_Output = 0.
Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C )
On Wed, Jan 02, 2002 at 05:37:28PM +0100, Mattia Barbon wrote: I don't care for the variable name, but I'd really like to have this feature. Would it work ok as a Test::Builder accessor method rather than an environment variable? No, unfortunately, because the call order is like this: * init code in the backend * BEGIN blocks of the program ( including use Foo; ) * B::Backend::compile * the coderef returned by B::Backend::compile So I can't call the method from the init code in the backend, because Test::Builder hasn't been loaded yet, and calling it from the ::compile is too late ( output is already lost ); the alternative I see is to use a package variable; so I can set $Test::Builder::i_want_the_output_even_if_dollar_caret_C_is_1 = 1; in initialization code. But I rwally like the environment variable better, because with the package variable solution I need to set it unconditionally ( because for it to have effect it must be set in the init code, and in the init code I can't look at parameters, because parameters are passed in the call to compile, so I can't set it using a parameter ), and because I was hoping to keep B::C clear from hacks-to-make-the-testsuite-happy. Regards Mattia
Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C )
On Sat, Jan 05, 2002 at 10:17:34PM +0100, Mattia Barbon wrote: On Wed, Jan 02, 2002 at 05:37:28PM +0100, Mattia Barbon wrote: I don't care for the variable name, but I'd really like to have this feature. Would it work ok as a Test::Builder accessor method rather than an environment variable? No, unfortunately, because the call order is like this: * init code in the backend * BEGIN blocks of the program ( including use Foo; ) * B::Backend::compile * the coderef returned by B::Backend::compile So I can't call the method from the init code in the backend, because Test::Builder hasn't been loaded yet, and calling it from the ::compile is too late ( output is already lost ); the alternative I see is to use a package variable; so I can set $Test::Builder::i_want_the_output_even_if_dollar_caret_C_is_1 = 1; in initialization code. You could do this: require Test::Builder; my $tb = Test::Builder-new; $tb-output_even_if_compiling(1); in the init code. Since Test::Builder is a singleton your settings should stick. Here's an interesting alternative. Do Clocal $^C = 0 just before running the tests, though that's pretty ugly. But I rwally like the environment variable better, because with the package variable solution I need to set it unconditionally ( because for it to have effect it must be set in the init code, and in the init code I can't look at parameters, because parameters are passed in the call to compile, so I can't set it using a parameter ), and because I was hoping to keep B::C clear from hacks-to-make-the-testsuite-happy. From my PoV, I'm hoping to keep Test::Builder clear from hacks-to-make-perlcc-happy. :) The $^C thing is already a hack for B::Deparse. Could you explain again why you need test output while compiling, I'm not quite following. Assume you had the I_WANT_OUTPUT_DURING_COMPILE environment variable could you show how you'd be using it? -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ Perl Quality Assurance [EMAIL PROTECTED] Kwalitee Is Job One Skrewtape I've heard that semen tastes different depending on diet. Is that true? Skrewtape Hello? Schwern Skrewtape: Hang on, I'm conducting research.