Re: PATCH porting.pod First Mystery

2003-09-05 Thread Brian McCauley
Stas Bekman [EMAIL PROTECTED] writes:

 local is perl4-ism, nowadays it's used only for localizing special
 perl variables, like $|.

Using package variables and local() in to do the job of block-scoped
lexicals is a Perl4-ism.

On the other hand, when using global variables (in which I include
Perl's package variables and Perl's file-scoped lexicals) something
with the semantics of local() is useful.  It is, therefore, annoying
that local cannot be used on lexical variables and even LW has said
that this restriction is artifical and wrong.

I agree that as a programming technique global variables are vulgar.
However the First Mystery is all about porting CGI scripts that are
already using global variables (implemented using file-scoped
lexicals).  It is the use of global variables in the first place that
is vulgar, using local() does not make the code any more vulgar.
 
  Secongly it's a smaller change.
 
 Agreed, but it's not the proper change, your change can break
 code.

Only in really obscure circumstances.  Of course, if at the same time,
you make an unrelated change that breaks the code I can see how you'd
be tempted to blame me. :-)

 Assuming that we had:
 
 use warnings;
 my $counter = 0;
 print hit $counter times;
 
 Your change:
 
 use warnings;
 local our $counter;
 print hit $counter times;

No, that's not my change, I said to change my to local our.  I
didn't say to remove initialization.

  Anyhow, local() does something quite different.  It undefines it upon
  exit of the current scope.

 On the exit of the scope local() restores the previous value if any,
 and if none was assigned in first place (which implies undef) it's
 reset to undef. 

Yes, I know that.

 I don't think it has anything to do with finalization, it just looks
 like it does.

Bluebells are not blue, they are actually pink and just look like
they are blue :-)

I use the term 'finalization' to (amongst other things) refer to
declaring an action that is to take place when a given scope is
removed from the execution stack.  This is what 'local' does.
The word, however, is not important as I don't propose to use it in
the guide.

 However I'm not against your 'local our' solution, I'm just saying
 that it's less obvious than an explicit initialization, even though it
 requires more modification. Not-very advanced users will just get
 confused by this solution. Normally variables need to be initialized
 before they are used, so they will have to init them in any case and
 undef is not what they want.

The porting guide assumes we start with a working CGI script.  If a
variable needs to be initialized to a value other than undef then a
working script must already do so.

 For example we can provide an explicit initialization example

The example in my modified porting.pod already shows explicit
initialization:

  local our $counter = 0;

 after that suggest that you can say 'local our $foo' to globalize and
 localize it at the same time if you prefer to init those to undef via
 local(). Sounds like a good compromise to me.

That fails to mention the real reason for using local.

  [ about use vars ]
 The guide is written to reduce the number of questions, not raise
 their number. Solution: mention both (our and use vars)

How about we leave the example as I have it now and say:

   In this simple example, 'local' is redundant because $counter is
   explicitly initialized and never holds a reference.  For variables
   that hold references (especially to objects interfacing to entities
   outside Perl) 'local' ensures timely destruction.  For variables
   lacking explicit initialization 'local' also initializes them to
   undefined.

   The 'our' function appeared in 5.6, for backward compatability:

  use vars qw( $counter );
  $counter = 0;

We could also go on to talk about the option of explicitly
initializing variables with undef() to save the minute overhead of
using local() but I think that's unwarranted in porting.pod.  Perhaps
it should be covered in perl_reference.pod.

  [ file handle example ]
 
 I didn't suggest that particular use

I realise that the simple file handle example was a poor choice to
illustrate my point.  Here's a better example that could form the
basis of a more verbose explation in perl_reference.pod.

Suppose you have:

 my $thing = Thing-new;

Now suppose that Thing objects involve lots of resources (shared
memory segments, temporary files, large Perl data structures,
network connections various database/NNTP/SNPP/whatever servers
and so on) and/or suppose that Thing objects perform some sort of
output buffering and then flush it in Thing::DESTROY.

If I change that to:

 our $thing = Thing-new;

Then all of these resources are held until the script is next run
or until the interpreter thread is killed.

If I change it to:

 local our $thing = Thing-new;

It does the right thing.

You might think you could simply undef($thing) 

Re: PATCH porting.pod First Mystery

2003-09-05 Thread Stas Bekman
Brian McCauley wrote:
[...]
OK, your last post's examples were more to the point of wanting to destroy 
objects at the end of the request, and hence here is a new summary:

- move the perl4 lib solution to the perl_reference.pod
- suggest turning a lexical variable declared with my() into a global variable 
declared with our() to avoid the closure, with the following buts:

  o if with my() it wasn't crucial to initialize the variables
   (since my() initialized them to 'undef'), now all variables declared with
   our() must be explicitly initialized.
 s/my $counter = 0/our $counter = 0/;

[Brian: notice that I prefer *not* to suggest using local() to init vars, and 
rather have users do that explicitly, which is a good practice]

  o since the initialization of global variables happens at the beginning of
the request, if a variable which contains an object:
  my $query = CGI-new;

is made global:

  our $query = CGI-new;

it won't be destroyed untill the next request. If you wish to make sure
that it's destroyed at the end of the request, you must local()'ize the
variable:
  local our $query = CGI-new;

- users of perl  5.6 have to use 'use vars' instead of 'our'. So the above 
examples become:

   use vars qw($counter);
   $counter = 0;
and:

   use vars qw($query);
   local $query = CGI-new;
- point to perl_reference.pod for other workarounds/solutions.

Please let me know if I have missed something from your last posts suggestions.

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html


Re: PATCH porting.pod First Mystery

2003-09-03 Thread Brian McCauley
Stas Bekman [EMAIL PROTECTED] writes:

 Brian McCauley wrote:
 [...]
 Nice, but:
 
   +The easiest and the fastest way to solve the nested subroutines
   +problem is to change Cmy to Clocal Cour for all variables for
   +which you get the warning.  The Chandler subroutines are never
 ...
 [...]
   +  local our $counter = 0;
 
 local our? That should be either local or our, but not both.
  No.
 
 Do I miss something?
  Yes.  (I tried to explain this in Paris but I was in danger of
  causing
  you to miss lunch completely).
  local() and our() do two quite separate and complementary things.
  our() (in effect) declares a lexically scoped alias for a package
  variable.
  local() restores the old value of a package variable (usually undef)
  at the end of the current lexical scope.
 
 In effect you use local() to undef the variable, instead of explicitly
 initializing it. Why not doing this explictly?

Firstly it's conceptually neater to use local.  I want to think of the
variable as local rather than as a global variable that needs to be
explicitly reset.

Secongly it's a smaller change.

Thirdly you can never be sure the undef would be reached. (I realise
after reading the rest of your mail that that statement will not make
any sense to you because you've misunderstood what local does and
hense where the undef would need to go).

 so instead of replacing:
 
 my $counter;
 
 with:
 
 local our $counter;
 
 it's probably better to say:
 
 our $counter = 0;

Surely you meant:

 undef our $counter;

Or 

  our $counter = undef.

In this case $counter is treated a a number so it's OK to use 0 but
the aim of the game is to come up with a drop-in replacement for all
lexically scoped variables that suffer will not remain shared.

Anyhow, local() does something quite different.  It undefines it upon
exit of the current scope.  Obviously _most_ of the time it matters
little if the variable is undef on exiting the scope or re-entering it
next time.  But why bother storing up troubles.  Better to do the
right thing from the outset.

 or if you insist on using both:
 
 our $counter;
 local $counter; # undef $counter

Why split them?  Doesn't aid readability.  Is a pain if the original
my() was inside an expression.

The comment is confusing.  It implies that local performs
initialization.  It doesn't.  It performs finalization.

The comment should read:

 local $counter; # Automatically undef $counter when script terminates

 later on I show why this is better for user's understanding.

Really?

  The two combined therefore give a package variable two of the most
  useful properties of a lexical one.  Of course a real lexical variable
  doesn't really become undefined when it does out of scope - it really
  becomes anonymous, and iff there are no remaining (unweakened)
  references it then gets GCed.  But for file-scoped lexicals in the
  main script file the difference is usually not that important.  Both
  effectively get killed at the point where global destruction would
  have taken place.
 
 The rest looks good, but that's not the simplest solution as you have
 to modify the variables.
  Is there a simpler one?  For a typical script with say half a dozen
  variables the would not remain shared the local our solution
  requires a dozen keystokes on each of half a dozen lines.
 
 Don't forget that our() is not available before perl 5.6. So we can't
 quite eliminate the previous solution unless you suggest to go with a
 back-compatible version:
 
 use vars qw($counter);
 local $counter;

I thought enough time has gone by that 5.6 can be considered the norm
and the tiny fraction of people doing on-going work on legacy pre-5.6
system should be expected to be familar with the work-rounds required.
On that basis I concuded that the work-rounds needed to get arround
the lack of our() in 5.5 are outside the scope of the the porting
document and belonged in the perl_reference.  In my (as yet
incomplete) revision of the perl_reference document I include mention
of 'use vars'.  If you think this should be in porting I'm not going
to argue.

 and of course the proper solution is:
 
 use vars qw($counter);
 $counter = 0; # or undef

No, the proper solution is:

  local our $counter;
 
IMNSHO use vars is not the proper solution, it is a backward
compatability work-round for people still using old versions of Perl
that prevent them using the proper solution.

Initialization is not the proper solution.  In some cases, like the
case of the simple counter you can get away with using initialization.
But the proper solution is finalization (using local).  To see why
consider a CGI script that contains, at file scope:

  open my $file, '', $outfile or die $outfile: $!;

What happens if you change that to:

  use vars qw($file);
  $file = undef;
  open $file, '', $outfile or die $!;

Well firstly it looks way ugly :-) !  Much more importantly it doesn't
close the file when the script terminates.

  open local our $file, '', $outfile or 

Re: PATCH porting.pod First Mystery

2003-09-03 Thread Stas Bekman
[...]
In effect you use local() to undef the variable, instead of explicitly
initializing it. Why not doing this explictly?


Firstly it's conceptually neater to use local.  I want to think of the
variable as local rather than as a global variable that needs to be
explicitly reset.
local is perl4-ism, nowadays it's used only for localizing special perl 
variables, like $|.

Secongly it's a smaller change.
Agreed, but it's not the proper change, your change can break code. Assuming 
that we had:

use warnings;
my $counter = 0;
print hit $counter times;
Your change:

use warnings;
local our $counter;
print hit $counter times;
will generate a warning: Use of uninitialized value in concatenation (.) or 
string at ...

We have to teach users to initialize globals, not localize them. See more below.

Thirdly you can never be sure the undef would be reached.
And nobody wants it to be reached. The problem is at the beginning of the 
subsequent request, not at the end of the first request. See more below.

so instead of replacing:

my $counter;

with:

local our $counter;

it's probably better to say:

our $counter = 0;


Surely you meant:

 undef our $counter;

Or 

  our $counter = undef.
No I meant = 0, because that's what the original example does. We try to solve 
the problem with:

my $counter = 0;

therefore:

our $counter = 0;

does the trick. if you replace

my $counter = 0;

with

local our $counter;

you lose the initialization. This won't work under 'use warnings', which is 
not clear from the example, but perhaps it should be fixed to do that.

In this case $counter is treated a a number so it's OK to use 0 but
the aim of the game is to come up with a drop-in replacement for all
lexically scoped variables that suffer will not remain shared.
Anyhow, local() does something quite different.  It undefines it upon
exit of the current scope.  Obviously _most_ of the time it matters
little if the variable is undef on exiting the scope or re-entering it
next time.  But why bother storing up troubles.  Better to do the
right thing from the outset.
I beg your pardon, how did you come up to this conclusion. Point me to the 
documentation or the source code where this is done. On the exit of the scope 
local() restores the previous value if any, and if none was assigned in first 
place (which implies undef) it's reset to undef. I don't think it has anything 
to do with finalization, it just looks like it does.

Your code:

local our $counter;

is essentially:

our $counter; # undef
{ local $counter; # new undef unrelated to the previous one
  $counter = 0; # you missed this, but it's unrelated
}
# $counter == the very first undef here, because it was undef before local was 
called.

And just to prove you that you aren't so correct with this finalization idea, 
run the following code:

perl-5.8.1 -lwe 'our $x = 5; { local $x = 6 } print $x'

it prints '5', not undef. so it's *restored* to its previous value not reset 
to undef. now this:

perl-5.8.1 -lwe 'our $x; { local $x = 6 } print $x'

will indeed restore $x to undef, because that's how it was before local...

However I'm not against your 'local our' solution, I'm just saying that it's 
less obvious than an explicit initialization, even though it requires more 
modification. Not-very advanced users will just get confused by this solution. 
 Normally variables need to be initialized before they are used, so they will 
have to init them in any case and undef is not what they want.

For example we can provide an explicit initialization example and after that 
suggest that you can say 'local our $foo' to globalize and localize it at the 
same time if you prefer to init those to undef via local(). Sounds like a good 
compromise to me.

I thought enough time has gone by that 5.6 can be considered the norm
and the tiny fraction of people doing on-going work on legacy pre-5.6
system should be expected to be familar with the work-rounds required.
On that basis I concuded that the work-rounds needed to get arround
the lack of our() in 5.5 are outside the scope of the the porting
document and belonged in the perl_reference.  In my (as yet
incomplete) revision of the perl_reference document I include mention
of 'use vars'.  If you think this should be in porting I'm not going
to argue.
That's what I suggested, just wasn't clear about it. It should be moved out of 
porting.pod into perl_reference.pod.

IMNSHO use vars is not the proper solution, it is a backward
compatability work-round for people still using old versions of Perl
that prevent them using the proper solution.
Well, what users that do happen to use perl  5.6 should do? The guide is 
written to reduce the number of questions, not raise their number. Solution: 
mention both (our and use vars)

Initialization is not the proper solution.  In some cases, like the
case of the simple counter you can get away with using initialization.
But the proper solution is finalization (using local).  To see why
consider a CGI 

Re: PATCH porting.pod First Mystery

2003-09-03 Thread Perrin Harkins
On Wed, 2003-09-03 at 21:24, Stas Bekman wrote:
 [...]
 In effect you use local() to undef the variable, instead of explicitly
 initializing it. Why not doing this explictly?
  
  
  Firstly it's conceptually neater to use local.  I want to think of the
  variable as local rather than as a global variable that needs to be
  explicitly reset.
 
 local is perl4-ism, nowadays it's used only for localizing special perl 
 variables, like $|.

I agree, using local, and especially local our is pretty strange.  It
may work, but I wouldn't want to encourage people to do that in their
code.

 To summarize:
 
 - move the perl4 lib solution to the perl_reference.pod
 - suggest replacing my() with our() to avoid the closure, however this change 
 requires that the variables will be initialized before used in most cases 
 (example of 'open our $foo' which doesn't need to be initialized). you can 
 initialize variables by an explicit assignment of the value, or using the 
 'local our' trick, which will initialize the variable to under, which is 
 probably not what you want.
 - for users of perl  5.6 suggest to use 'use vars' instead of 'our'.
 - point to perl_reference.pod for other workarounds/solutions.

May I also suggest telling users to pass arguments explicitly to subs,
instead of doing it implicitly?  Nearly all of the Registry-related bugs
I see stem from people doing this:

my $cgi = CGI-new();

foo()

sub foo {
  $cgi-param(whatever)...
}

They accidentally create a closure this way and then wonder why their
form values never change.  Passing $cgi to foo() fixes the problem.

- Perrin



-- 
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html



Re: PATCH porting.pod First Mystery

2003-09-03 Thread Stas Bekman
Perrin Harkins wrote:

To summarize:

- move the perl4 lib solution to the perl_reference.pod
- suggest replacing my() with our() to avoid the closure, however this change 
requires that the variables will be initialized before used in most cases 
(example of 'open our $foo' which doesn't need to be initialized). you can 
initialize variables by an explicit assignment of the value, or using the 
'local our' trick, which will initialize the variable to under, which is 
probably not what you want.
- for users of perl  5.6 suggest to use 'use vars' instead of 'our'.
- point to perl_reference.pod for other workarounds/solutions.


May I also suggest telling users to pass arguments explicitly to subs,
instead of doing it implicitly?  Nearly all of the Registry-related bugs
I see stem from people doing this:
my $cgi = CGI-new();

foo()

sub foo {
  $cgi-param(whatever)...
}
They accidentally create a closure this way and then wonder why their
form values never change.  Passing $cgi to foo() fixes the problem.
We have that already covered in perl_reference.pod, example multirun3.pl. 
Originally all the workarounds were in the porting.pod but then there were too 
many of them. so I thought to give just one solution and a pointer to a 
document/section with the rest of the solutions. If you think it's worth 
mentioning it in porting.pod in addition to the current place, feel free to 
adjust it. Your above example prabably more familiar to cgi script writers, 
than an abstract $counter exapmle.

Thanks!

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html


Re: PATCH porting.pod First Mystery

2003-09-02 Thread Stas Bekman
Brian McCauley wrote:
[...]
Nice, but:

 +The easiest and the fastest way to solve the nested subroutines
 +problem is to change Cmy to Clocal Cour for all variables for
 +which you get the warning.  The Chandler subroutines are never
...
[...]
 +  local our $counter = 0;
local our? That should be either local or our, but not both.


No.


Do I miss something?


Yes.  (I tried to explain this in Paris but I was in danger of causing
you to miss lunch completely).
local() and our() do two quite separate and complementary things.

our() (in effect) declares a lexically scoped alias for a package
variable.
local() restores the old value of a package variable (usually undef)
at the end of the current lexical scope.
In effect you use local() to undef the variable, instead of explicitly 
initializing it. Why not doing this explictly?

so instead of replacing:

my $counter;

with:

local our $counter;

it's probably better to say:

our $counter = 0;

or if you insist on using both:

our $counter;
local $counter; # undef $counter
later on I show why this is better for user's understanding.

The two combined therefore give a package variable two of the most
useful properties of a lexical one.  Of course a real lexical variable
doesn't really become undefined when it does out of scope - it really
becomes anonymous, and iff there are no remaining (unweakened)
references it then gets GCed.  But for file-scoped lexicals in the
main script file the difference is usually not that important.  Both
effectively get killed at the point where global destruction would
have taken place.
 

The rest looks good, but that's not the simplest solution as you have
to modify the variables.


Is there a simpler one?  For a typical script with say half a dozen
variables the would not remain shared the local our solution
requires a dozen keystokes on each of half a dozen lines.
Don't forget that our() is not available before perl 5.6. So we can't quite 
eliminate the previous solution unless you suggest to go with a 
back-compatible version:

use vars qw($counter);
local $counter;
and of course the proper solution is:

use vars qw($counter);
$counter = 0; # or undef
which is documented in the perl reference section.

Granted, the original simplest solution has its troubles.


The original simplest solution involved finding (and subsequently
maintaining) a globally unique filename then splitting the program in
to two parts.  Thereafer you have to maintain two files even on CGI
servers.  I would contend that this simple solution is not simple.
If you are going to all that troble you may as well to the extra
804.65m and produce a proper mod_perl handler and a small wrapper to
make it work also in a CGI environment.  Also, as of mod_perl2, the
simple solution is not even, as it stands, a solution as it relied
on the script being in the CWD.
Remember, we are talking about mp1 guide patching. Not everything that applies 
to mp1 applies to mp2. e.g., mp2 requires 5.6+, so we indeed can rely on using 
our() there. And I hope that the problem with CWD will be resolved once Arthur 
will fix that.

If you think that using globals + their initialization is a better solution, 
which will work well in mp1 and mp2, we can replace the lib.pl solution with 
it, but should add it to the perl reference section.

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html


Re: PATCH porting.pod First Mystery

2003-09-01 Thread Brian McCauley
Stas Bekman [EMAIL PROTECTED] writes:

 [EMAIL PROTECTED] wrote:
  In private mail Stas Bekman [EMAIL PROTECTED] writes:
 
 oops, that should be the modperl list... at modperl-docs we discuss
 mostly site/docs techical issues and there are very few people on this
 list to get enough exposure for this kind of feedback request.
  Patch for The First Mystery section of the mod_perl porting guide
  as
  per my conversation with Stas at YAPC::Europe::2003.
  Takes out the suggestion of creating a Perl4-style library in the
  same
  directory as a means to port CGI scripts.
  Replaces it with something simpler and more reliable.
 
 Nice, but:
 
   +The easiest and the fastest way to solve the nested subroutines
   +problem is to change Cmy to Clocal Cour for all variables for
   +which you get the warning.  The Chandler subroutines are never
 ...
 [...]
   +  local our $counter = 0;
 
 local our? That should be either local or our, but not both.

No.

 Do I miss something?

Yes.  (I tried to explain this in Paris but I was in danger of causing
you to miss lunch completely).

local() and our() do two quite separate and complementary things.

our() (in effect) declares a lexically scoped alias for a package
variable.

local() restores the old value of a package variable (usually undef)
at the end of the current lexical scope.

The two combined therefore give a package variable two of the most
useful properties of a lexical one.  Of course a real lexical variable
doesn't really become undefined when it does out of scope - it really
becomes anonymous, and iff there are no remaining (unweakened)
references it then gets GCed.  But for file-scoped lexicals in the
main script file the difference is usually not that important.  Both
effectively get killed at the point where global destruction would
have taken place.
 
 The rest looks good, but that's not the simplest solution as you have
 to modify the variables.

Is there a simpler one?  For a typical script with say half a dozen
variables the would not remain shared the local our solution
requires a dozen keystokes on each of half a dozen lines.

 Granted, the original simplest solution has its troubles.

The original simplest solution involved finding (and subsequently
maintaining) a globally unique filename then splitting the program in
to two parts.  Thereafer you have to maintain two files even on CGI
servers.  I would contend that this simple solution is not simple.
If you are going to all that troble you may as well to the extra
804.65m and produce a proper mod_perl handler and a small wrapper to
make it work also in a CGI environment.  Also, as of mod_perl2, the
simple solution is not even, as it stands, a solution as it relied
on the script being in the CWD.


-- 
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html



Re: PATCH porting.pod First Mystery

2003-08-30 Thread Stas Bekman
[EMAIL PROTECTED] wrote:
In private mail Stas Bekman [EMAIL PROTECTED] writes:


oops, that should be the modperl list... at modperl-docs we discuss
mostly site/docs techical issues and there are very few people on this
list to get enough exposure for this kind of feedback request.


Patch for The First Mystery section of the mod_perl porting guide as
per my conversation with Stas at YAPC::Europe::2003.
Takes out the suggestion of creating a Perl4-style library in the same
directory as a means to port CGI scripts.
Replaces it with something simpler and more reliable.
Nice, but:

 +The easiest and the fastest way to solve the nested subroutines
 +problem is to change Cmy to Clocal Cour for all variables for
 +which you get the warning.  The Chandler subroutines are never
...
[...]
 +  local our $counter = 0;
local our? That should be either local or our, but not both. Do I miss something?

The rest looks good, but that's not the simplest solution as you have to 
modify the variables. Granted, the original simplest solution has its troubles.

I've also changed If you put your code into a library or module...
to If you put all your code into modules... because if you put your
code into a Perl4-style library and then require it in more than one
registry script terrible things happen.  I don't think this is the
place to explain this so I think the guide should just say modules
and leave it at that.  

Probably the library problem should be explained elsewhere in the
guide.
Once this one is sorted out, a patch for perl_reference.pod will follow.
Sure, sounds good to me.

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html