Revert "[perl #95550] Remove prototypes from (l)stat"
authorFather Chrysostomos <sprout@cpan.org>
Fri, 12 Aug 2011 05:15:05 +0000 (22:15 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 12 Aug 2011 13:28:09 +0000 (06:28 -0700)
It turns out this problem is more knotty than I initially realised.
stat had a prototype of (*), even though it could be called with no
arguments.  Since the (*) prototype does not parse its argument the
same way that stat parses *its* argument, I thought that changing (*)
to (;*) would be no better, since it’s still not correct.  So I simply
set the prototype to undef.

My thinking was faulty, for two reasons:

• The prototype serves to indicate the precedence, not just the types
  of arguments.  An undefined prototype on an overridable prefix func-
  tion implies that it takes a list.  So this causes problems for the
  imminent &CORE::subs feature, as there is not yet a clean mechanism
  for CVs to parse their arguments.
• The (*) prototype character does not parse the same way as *any*
  built-in function with that character in its prototype.  So stat is
  no worse than any other built-in.  It doesn’t make sense to remove
  the prototype from stat without removing it from about 40 other
  built-in functions; and that’s where pedantry conflicts with
  usefulness.

This commit restores the (*) prototype to stat and lstat.  The next
commit will give it a (;*) prototype, as that matches it more closely.
It’s not perfect, but it’s no worse that other built-ins with a * in
their prototypes.

op.c
pod/perldelta.pod
t/op/cproto.t

diff --git a/op.c b/op.c
index af2f3cac571e65dd3d6f71d4ae03b7378ed2c3fc..b42069a6347476c95f57a31647c553a841678f2a 100644 (file)
--- a/op.c
+++ b/op.c
@@ -10282,8 +10282,8 @@ Perl_core_prototype(pTHX_ SV *sv, const char *name, const STRLEN len,
     case KEY_and   : case KEY_chop: case KEY_chomp:
     case KEY_cmp   : case KEY_exec: case KEY_eq   :
     case KEY_ge    : case KEY_gt  : case KEY_le   :
-    case KEY_lstat : case KEY_lt  : case KEY_ne   : case KEY_or :
-    case KEY_stat  : case KEY_system: case KEY_x  : case KEY_xor:
+    case KEY_lt    : case KEY_ne  : case KEY_or   :
+    case KEY_system: case KEY_x   : case KEY_xor  :
        return NULL;
     case KEY_keys: case KEY_values: case KEY_each:
        retsetpvs("+");
index ba0d3a51f2be712b7e508a9b7088233feb67bc2c..120cafec0a67002395d0a2081fd3b2ed300a66a9 100644 (file)
@@ -462,12 +462,6 @@ was just wrong.
 
 =item *
 
-The prototypes for the core functions C<stat> and C<lstat> have been
-removed, as they were incorrect, because their syntax cannot be replicated
-by Perl subroutines.
-
-=item *
-
 Most dereferencing operators (C<${}>, etc.) used to call C<FETCH> twice on
 a tied operand when doing a symbolic dereference (looking up a variable by
 name, which is not permitted under C<use strict 'refs'>).  Only C<&{}> did
index e1f3125dfcc271c859cbb871b1f406cefb27a78d..7d63c6893fc9cbe80a81412fcdcd3f2fb9f86baf 100644 (file)
@@ -140,7 +140,7 @@ local undef
 localtime (;$)
 lock (\[$@%*])
 log (_)
-lstat undef
+lstat (*)
 lt undef
 m undef
 map undef
@@ -227,7 +227,7 @@ split undef
 sprintf ($@)
 sqrt (_)
 srand (;$)
-stat undef
+stat (*)
 state undef
 study undef
 sub undef