OP *
Perl_ck_sort(pTHX_ OP *o)
{
+ OP *firstkid;
o->op_private = 0;
#ifdef USE_LOCALE
if (PL_hints & HINT_LOCALE)
if (o->op_type == OP_SORT && o->op_flags & OPf_STACKED)
simplify_sort(o);
- if (o->op_flags & OPf_STACKED) { /* may have been cleared */
- OP *kid = cLISTOPo->op_first->op_sibling; /* get past pushmark */
+ firstkid = cLISTOPo->op_first->op_sibling; /* get past pushmark */
+ if (o->op_flags & OPf_STACKED) { /* may have been cleared */
OP *k;
- kid = kUNOP->op_first; /* get past null */
+ OP *kid = cUNOPx(firstkid)->op_first; /* get past null */
if (kid->op_type == OP_SCOPE || kid->op_type == OP_LEAVE) {
linklist(kid);
}
peep(k);
- kid = cLISTOPo->op_first->op_sibling; /* get past pushmark */
- if (o->op_type == OP_SORT)
+ kid = firstkid;
+ if (o->op_type == OP_SORT) {
+ /* provide scalar context for comparison function/block */
+ kid = scalar(kid);
kid->op_next = kid;
+ }
else
kid->op_next = k;
o->op_flags |= OPf_SPECIAL;
}
else if (kid->op_type == OP_RV2SV || kid->op_type == OP_PADSV)
- null(cLISTOPo->op_first->op_sibling);
+ null(firstkid);
+
+ firstkid = firstkid->op_sibling;
}
+ /* provide list context for arguments */
+ if (o->op_type == OP_SORT)
+ list(firstkid);
+
return o;
}
unshift @INC, '../lib';
}
use warnings;
-print "1..49\n";
+print "1..55\n";
# XXX known to leak scalars
{
@b = sort main::Backwards_stacked @a;
print ("@b" eq '90 5 255 1996 19' ? "ok 49\n" : "not ok 49\n");
print "# x = '@b'\n";
+
+# check if context for sort arguments is handled right
+
+$test = 49;
+sub test_if_list {
+ my $gimme = wantarray;
+ print "not " unless $gimme;
+ ++$test;
+ print "ok $test\n";
+}
+my $m = sub { $a <=> $b };
+
+sub cxt_one { sort $m test_if_list() }
+cxt_one();
+sub cxt_two { sort { $a <=> $b } test_if_list() }
+cxt_two();
+sub cxt_three { sort &test_if_list() }
+cxt_three();
+
+sub test_if_scalar {
+ my $gimme = wantarray;
+ print "not " if $gimme or !defined($gimme);
+ ++$test;
+ print "ok $test\n";
+}
+
+$m = \&test_if_scalar;
+sub cxt_four { sort $m 1,2 }
+@x = cxt_four();
+sub cxt_five { sort { test_if_scalar($a,$b); } 1,2 }
+@x = cxt_five();
+sub cxt_six { sort test_if_scalar 1,2 }
+@x = cxt_six();