develooper Front page | perl.perl5.porters | Postings from March 2000

Efficient English.pm

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.



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About