Front page | perl.perl5.porters |
Postings from March 2000
Efficient English.pm
Thread Previous
|
Thread Next
From:
Tye McQueen
Date:
March 15, 2000 12:05
Subject:
Efficient English.pm
Message ID:
200003152005.AA28713@metronet.com
By accident I ran into perlvars.pod and noted that English.pm is
heavilly documented in such central documentation but its use is
also strongly discouraged because it slows down regexen. So I
fixed that, as detailed in the appended patch.
Researching further I found at least 3 previous attempts at this.
So I stopped working the patch before I got to the documentation.
Should I extend this patch to cover the documentation or should I
just write a documentation patch that says: "but please don't
send patches to fix English.pm -- we have several and we're just
going to wait until we can make $`, $&, $' not slow anymore"?
[or whatever the reason is -- I never found any actual responses
to these patches stating why they were never included]
My patch allows:
use English "!:SLOW";
which doesn't slow down regexen. It uses standard Exporter.pm
features. It also fixes some bugs in the C<import> that didn't
just grandfather in $NAME imports but also prevented *NAME
imports. The patch also allows the even better:
use English qw( ERRNO PID UID );
and it correctly determines whether "slow" variables were requested
even if you do something really complex or strange like:
use English qw( /AT/ !/MATCH$/ /_/ );
and, yes, it passes the Devel::SawAmpersand test.
[and C<Exporter::export()> really should be split into pieces so
you can request the very fancy selection of a list of symbols-to-
be-exported separate from actually exporting them -- feel free to
encourage me to submit that patch if you've wanted this as well.]
But English.pm's documentation also mentions:
You should I<not> use this module in programs intended to be portable
among Perl versions,
I finally found that this refers to some variables failing
when threading is enabled. So I renew the request for any
variables to add to the list beside:
$ARG ($_)
$LIST_SEPARATOR ($")
$EVAL_ERROR ($@)
And I'll patch the documentation to include this information
whether the list is determined to be complete or not.
Oops, I was supposed to send this via perlbug. That would require
actually building and installing perl5.005_63. Should I A) use
perl5.005_03's perlbug for future patches [in this case,
English.pm didn't change between the versions], B) just be sure
to note exactly what version my diffs are against, C) perlbug is
essential and I should just spend the time building and installing,
or D) something else?
Thanks,
Tye
--- perl5.005_63/lib/english.pm Thu Jan 06 20:58:38 2000
+++ patched/lib/english.pm Tue Mar 14 16:37:36 2000
@@ -39,14 +39,34 @@
local $^W = 0;
-# Grandfather $NAME import
+my $slow = 0; # Whether we've already slowed Perl down.
+
+# Grandfather $NAME import. Allow NAME import, not just *NAME.
sub import {
my $this = shift;
my @list = @_;
- local $Exporter::ExportLevel = 1;
- Exporter::import($this,grep {s/^\$/*/} @list);
+ @list = grep {s#^\$?([A-Z])#*$1# || 1} @list;
+ my $callpkg = caller($Export::ExportLevel);
+ Exporter::export( $this, $callpkg, @list );
+ if( ! $slow ) {
+ my @redo;
+ push @redo, "*MATCH" if exists ${$callpkg."::"}{MATCH};
+ push @redo, "*PREMATCH" if exists ${$callpkg."::"}{PREMATCH};
+ push @redo, "*POSTMATCH" if exists ${$callpkg."::"}{POSTMATCH};
+ if( @redo ) {
+ $slow = 1;
+ eval q{
+ *MATCH = *& ;
+ *PREMATCH = *` ;
+ *POSTMATCH = *' ;
+ 1;
+ } or die $@;
+ Exporter::export( $this, $callpkg, @redo );
+ }
+ }
}
+%EXPORT_TAGS = ( SLOW => [qw< *MATCH *PREMATCH *POSTMATCH >] );
@EXPORT = qw(
*ARG
*MATCH
@@ -105,10 +125,13 @@
*ARG = *_ ;
# Matching.
-
- *MATCH = *& ;
- *PREMATCH = *` ;
- *POSTMATCH = *' ;
+# Don't mention the evil variables at first. Use *+ as dummy placeholder:
+ *MATCH = *+ ;
+ *PREMATCH = *+ ;
+ *POSTMATCH = *+ ;
+# *MATCH = *& ;
+# *PREMATCH = *` ;
+# *POSTMATCH = *' ;
*LAST_PAREN_MATCH = *+ ;
# Input.
Thread Previous
|
Thread Next