In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/5d8ab95357a99a13e919b0e5c19f9a7abb06167d?hp=7c579eed878fc49f1db8118b45c262d16571a5c1>

- Log -----------------------------------------------------------------
commit 5d8ab95357a99a13e919b0e5c19f9a7abb06167d
Author: Nicholas Clark <[email protected]>
Date:   Mon Mar 7 10:27:17 2011 +0000

    Ensure that the C<exists &Errno::EFOO> idiom continues to work as 
documented.
    
    A change post-5.12 (probably 42607a60df6df19b) caused the documented idiom 
not
    to work if Errno was loaded after the C<exists> code had been compiled, as
    the compiler implicitly creates typeglobs in the Errno symbol table when it
    builds the optree for the C<exists code>.
-----------------------------------------------------------------------

Summary of changes:
 ext/Errno/Errno_pm.PL |   13 +++++++++++--
 ext/Errno/t/Errno.t   |   19 ++++++++++++++++++-
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/ext/Errno/Errno_pm.PL b/ext/Errno/Errno_pm.PL
index 5725de8..c38f309 100644
--- a/ext/Errno/Errno_pm.PL
+++ b/ext/Errno/Errno_pm.PL
@@ -356,14 +356,23 @@ EDQ
 print <<'ESQ';
     );
     # Generate proxy constant subroutines for all the values.
-    # We assume at this point that our symbol table is empty.
+    # Well, almost all the values. Unfortunately we can't assume that at this
+    # point that our symbol table is empty, as code such as if the parser has
+    # seen code such as C<exists &Errno::EINVAL>, it will have created the
+    # typeglob.
     # Doing this before defining @EXPORT_OK etc means that even if a platform 
is
     # crazy enough to define EXPORT_OK as an error constant, everything will
     # still work, because the parser will upgrade the PCS to a real typeglob.
     # We rely on the subroutine definitions below to update the internal 
caches.
     # Don't use %each, as we don't want a copy of the value.
     foreach my $name (keys %err) {
-        $Errno::{$name} = \$err{$name};
+        if ($Errno::{$name}) {
+            # We expect this to be reached fairly rarely, so take an approach
+            # which uses the least compile time effort in the common case:
+            eval "sub $name() { $err{$name} }; 1" or die $@;
+        } else {
+            $Errno::{$name} = \$err{$name};
+        }
     }
 }
 
diff --git a/ext/Errno/t/Errno.t b/ext/Errno/t/Errno.t
index 302bd8d..3baaf60 100644
--- a/ext/Errno/t/Errno.t
+++ b/ext/Errno/t/Errno.t
@@ -1,6 +1,9 @@
 #!./perl -w
 
-use Test::More tests => 10;
+use Test::More tests => 12;
+
+# Keep this before the use Errno.
+my $has_einval = exists &Errno::EINVAL;
 
 BEGIN {
     use_ok("Errno");
@@ -34,3 +37,17 @@ like($@, qr/^ERRNO hash is read only!/);
 # through Acme::MetaSyntactic::batman
 is($!{EFLRBBB}, "");
 ok(! exists($!{EFLRBBB}));
+
+SKIP: {
+    skip("Errno does not have EINVAL", 1)
+       unless grep {$_ eq 'EINVAL'} @Errno::EXPORT_OK;
+    is($has_einval, 1,
+       'exists &Errno::EINVAL compiled before Errno is loaded works fine');
+}
+
+SKIP: {
+    skip("Errno does not have EBADF", 1)
+       unless grep {$_ eq 'EBADF'} @Errno::EXPORT_OK;
+    is(exists &Errno::EBADF, 1,
+       'exists &Errno::EBADF compiled after Errno is loaded works fine');
+}

--
Perl5 Master Repository

Reply via email to