Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Swit

2002-01-15 Thread Tels

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

2002-01-14 Thread Rafael Garcia-Suarez

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

2002-01-14 Thread Piers Cawley

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

2002-01-14 Thread Mattia Barbon

 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?

2002-01-14 Thread Michael G Schwern

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

2002-01-14 Thread Piers Cawley

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

2002-01-14 Thread Michael G Schwern

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?

2002-01-14 Thread Michael G Schwern

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

2002-01-14 Thread Rafael Garcia-Suarez

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.