develooper Front page | perl.perl5.porters | Postings from October 2003

Fix for the orange lion bug - aka empty sub bug

Thread Next
From:
Arthur Bergman
Date:
October 30, 2003 14:02
Subject:
Fix for the orange lion bug - aka empty sub bug
Message ID:
A10EEA90-0B24-11D8-93CD-000A95A2734C@nanisky.com
So this is a fix for a bug in 5.8.1 that makes empty subs return @_ in 
list context (while returning nothing in scalar context).

Every other version of perl before 5.8.0 got this wrong but it is a 
side effect of other things. 5.8.0 got it right but because for a lack 
of a test case some change reverted back 5.8.1.

According to Larry (rule 1) the return @_ makes no sense and the sub 
should return nothing, here is a patch for this that arguably could be 
considered a hack, it inserts itself into the peep optimizer and checks 
for when a subroutine contains only a stub, it then replaces the stub 
with a nextstate. I strongly urge this go into 5.8.2, since 5.8.1 seems 
not to be wildly installed it would be good if we could establish that 
the 5.8 series does do the right thing.

(The importance if this bug fix is higher when you consider OO code 
that has base class methods that do nothing)

Arthur

--- perl-current-orig/MANIFEST	Thu Oct 30 19:38:49 2003
+++ perl-current/MANIFEST	Thu Oct 30 20:02:19 2003
@@ -2797,6 +2797,7 @@
  t/op/stash.t			See if %:: stashes work
  t/op/stat.t			See if stat works
  t/op/study.t			See if study works
+t/op/sub.t			See if subroutines work
  t/op/sub_lval.t			See if lvalue subroutines work
  t/op/subst_amp.t		See if $&-related substitution works
  t/op/substr.t			See if substr works
--- perl-current-orig/op.c	Thu Oct 30 19:38:49 2003
+++ perl-current/op.c	Thu Oct 30 21:51:41 2003
@@ -6277,6 +6277,17 @@
  	    o->op_seq = PL_op_seqmax++;
  	    break;
  	case OP_STUB:
+	    if(!oldop &&
+	       o->op_next &&
+	       o->op_next->op_type == OP_LEAVESUB) {
+	      OP* newop = newSTATEOP(0, Nullch, 0);
+	       newop->op_next = o->op_next;
+	       o->op_next = 0;
+       	       op_free(o);
+	       o = newop;
+       	       ((UNOP*)o->op_next)->op_first = newop;	
+	       CvSTART(PL_compcv) = newop;	
+	    }
  	    if ((o->op_flags & OPf_WANT) != OPf_WANT_LIST) {
  		o->op_seq = PL_op_seqmax++;
  		break; /* Scalar stub must produce undef.  List stub is noop */
--- /dev/null	Thu Oct 30 21:51:49 2003
+++ perl-current/t/op/sub.t	Thu Oct 30 20:01:44 2003
@@ -0,0 +1,14 @@
+
+
+use Test::More tests => 4;
+
+
+sub empty_sub {}
+
+is(empty_sub,undef,"Is empty");
+is(empty_sub(1,2,3),undef,"Is still empty");
+@test = empty_sub();
+is(scalar(@test), 0, 'Didnt return anything');
+@test = empty_sub(1,2,3);
+is(scalar(@test), 0, 'Didnt return anything');
+


Thread Next


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