Author: larry Date: Mon Apr 24 00:59:42 2006 New Revision: 8928 Modified: doc/trunk/design/syn/S02.pod
Log: Rules for parsing and compiling unrecognized identifiers. Modified: doc/trunk/design/syn/S02.pod ============================================================================== --- doc/trunk/design/syn/S02.pod (original) +++ doc/trunk/design/syn/S02.pod Mon Apr 24 00:59:42 2006 @@ -12,7 +12,7 @@ Maintainer: Larry Wall <[EMAIL PROTECTED]> Date: 10 Aug 2004 - Last Modified: 23 Apr 2006 + Last Modified: 24 Apr 2006 Number: 2 Version: 30 @@ -1531,7 +1531,67 @@ always be taken to mean a subroutine or method name. (Class names (and other type names) are predeclared, or prefixed with the C<::> type sigil when you're declaring a new one.) A consequence of this -is that there's no longer any "C<use strict 'subs'>". +is that there's no longer any "C<use strict 'subs'>". Since the syntax +for method calls is distinguished from sub calls, it is only unreconized +sub calls that must be treated specially. + +You still must declare your subroutines, but an unrecognized bare +identifier is provisionally compiled as a subroutine call on that +assumption that such a declaration will occur by the end of the current +compilation unit. If it is not, the compile fails at C<CHECK> time. +(You are still free to predeclare subroutines explicitly, of course.) +The postdeclaration may be in any lexical or package scope that +could have made the declaration visible to the provisional call had the +declaration occurred before rather than after than the provisional +call. This fixup is done only for provisional calls. If there +is I<any> real predeclaration visible, it always takes precedence. +In case of multiple ambiguous postdeclarations, either they must all +be multis, or a compile-time error is declared and you must predeclare, +even if one postdeclaration is obviously "closer". A single +C<proto> predeclaration may make all postdeclared C<multi> work fine, +since that's a run-time dispatch, and all multis are effectively +visible at the point of the controlling C<proto> declaration. + +If the unrecogized subname is followed by C<< postcircumfix:<( )> >>, it is +compiled as a provisional function call of the parenthesized form. +If it is not, it is compiled as a provisional function call of +the list operator form, which may or may not have an argument list. +When in doubt, the attempt is made to parse an argument list. As with +any list operator, an immediate postfix operator means there are no +arguments, whereas anything following whitespace will be interpreted +as an argument list if possible. It is illegal for a provisional +subroutine call to be followed by a colon postfix, since such a colon +is allowed only on an indirect object or a method call in dot form. +(It is also allowed on a label when a statement is expected.) +So for any undeclared identifier "C<foo>": + + foo.bar # foo().bar -- postfix prevents args + foo .bar # foo($_.bar) -- no postfix starts with whitespace + foo. .bar # foo().bar -- long dot, so postfix + foo++ # foo()++ -- postfix + foo 1,2,3 # foo(1,2,3) -- args always expected after listop + foo + 1 # foo(+1) -- term always expected after listop + foo; # foo(); -- no postfix, but no args either + foo: # label -- must be label at statement boundary. + -- illegal otherwise + foo: bar: # two labels in a row + .foo: # $_.foo: 1 -- must be "dot" method with : args + .foo(1) # $_.foo(1) -- must be "dot" method with () args + .foo # $_.foo() -- must be "dot" method with no args + .$foo: # $_.$foo: 1 -- indirect "dot" method with : args + foo bar: 1 # bar.foo(1) -- bar must be predecl as class or sub + -- foo method call even if declared sub + foo bar 1 # foo(bar(1)) -- both subject to postdeclaration + -- never taken as indirect object + foo $bar: 1 # $bar.foo(1) -- indirect object even if declared sub + foo bar(): # bar().foo(1) -- even if foo declared sub + foo bar baz: 1 # foo(bar baz: 1) -- colon controls "bar", not foo. + foo (bar baz): 1 # bar(baz()).foo(1) -- colon controls "foo" + $foo $bar # illegal -- two terms in a row + $foo $bar: # illegal -- use $bar.$foo for indirection + (foo bar) baz: 1 # illegal -- use $baz.$(foo bar) for indirection + +Parens are required around any indirect object that would be ambiguous. =item *