This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
detect sub attributes following a signature
[perl5.git] / t / op / signatures.t
index 8ab8db3..37fe166 100644 (file)
@@ -20,6 +20,13 @@ our $z;
     is $a, 123;
 }
 
+eval "#line 8 foo\nsub t004 :method (\$a) { }";
+like $@, qr{syntax error at foo line 8}, "error when not enabled 1";
+
+eval "#line 8 foo\nsub t005 (\$) (\$a) { }";
+like $@, qr{syntax error at foo line 8}, "error when not enabled 2";
+
+
 no warnings "experimental::signatures";
 use feature "signatures";
 
@@ -1136,7 +1143,7 @@ is eval("\$t103->(456, 789, 987)"), undef;
 like $@, qr/\AToo many arguments for subroutine 'main::__ANON__' at \(eval \d+\) line 1\.\n\z/;
 is $a, 123;
 
-my $t118 = sub ($a) :prototype($) { $a || "z" };
+my $t118 = sub :prototype($) ($a) { $a || "z" };
 is prototype($t118), "\$";
 is eval("\$t118->()"), undef;
 like $@, qr/\AToo few arguments for subroutine 'main::__ANON__' at \(eval \d+\) line 1\.\n\z/;
@@ -1202,7 +1209,7 @@ is eval("t132(sub { \"x\".(\$_[1] // sub{\$_[0]})->(\$_[0]).\"x\" }, 789)"),
 like $@, qr/\AToo many arguments for subroutine 'main::t132' at \(eval \d+\) line 1\.\n\z/;
 is $a, 123;
 
-sub t104($a) :method { $a || "z" }
+sub t104 :method ($a) { $a || "z" }
 is prototype(\&t104), undef;
 is eval("t104()"), undef;
 like $@, qr/\AToo few arguments for subroutine 'main::t104' at \(eval \d+\) line 1\.\n\z/;
@@ -1214,7 +1221,7 @@ is eval("t104(456, 789, 987)"), undef;
 like $@, qr/\AToo many arguments for subroutine 'main::t104' at \(eval \d+\) line 1\.\n\z/;
 is $a, 123;
 
-sub t105($a) :prototype($) { $a || "z" }
+sub t105 :prototype($) ($a) { $a || "z" }
 is prototype(\&t105), "\$";
 is eval("t105()"), undef;
 like $@, qr/\ANot enough arguments for main::t105 /;
@@ -1226,7 +1233,7 @@ is eval("t105(456, 789, 987)"), undef;
 like $@, qr/\AToo many arguments for main::t105 at \(eval \d+\) line 1, near/;
 is $a, 123;
 
-sub t106($a) :prototype(@) { $a || "z" }
+sub t106 :prototype(@) ($a) { $a || "z" }
 is prototype(\&t106), "\@";
 is eval("t106()"), undef;
 like $@, qr/\AToo few arguments for subroutine 'main::t106' at \(eval \d+\) line 1\.\n\z/;
@@ -1238,10 +1245,10 @@ is eval("t106(456, 789, 987)"), undef;
 like $@, qr/\AToo many arguments for subroutine 'main::t106' at \(eval \d+\) line 1\.\n\z/;
 is $a, 123;
 
-eval "#line 8 foo\nsub t107 :method (\$a) { }";
+eval "#line 8 foo\nsub t107(\$a) :method { }";
 isnt $@, "";
 
-eval "#line 8 foo\nsub t108 :prototype(\$) (\$a) { }";
+eval "#line 8 foo\nsub t108 (\$a) :prototype(\$) { }";
 isnt $@, "";
 
 sub t109 { }
@@ -1514,6 +1521,38 @@ while(<$kh>) {
     }
 }
 
+# RT #132141
+# Attributes such as lvalue have to come *before* the signature to
+# ensure that they're applied to any code block within the signature
+
+{
+    my $x;
+    sub f :lvalue ($a = do { $x = "abc"; return substr($x,0,1)}) {
+        die; # notreached
+    }
+
+    f() = "X";
+    is $x, "Xbc", "RT #132141";
+}
+
+# RT #132760
+# attributes have been moved back before signatures for 5.28. Ensure that
+# code doing it the old wrong way get a meaningful error message.
+
+{
+    my @errs;
+    local $SIG{__WARN__} = sub { push @errs, @_};
+    eval q{
+        sub rt132760 ($a, $b) :prototype($$) { $a + $b }
+    };
+
+    @errs = split /\n/, $@;
+    is +@errs, 1, "RT 132760 expect 1 error";
+    like $errs[0],
+        qr/^Subroutine attributes must come before the signature at/,
+        "RT 132760 err 0";
+}
+
 done_testing;
 
 1;