Last active
September 15, 2015 18:24
-
-
Save dha/8009c28d7bf2d1ca8875 to your computer and use it in GitHub Desktop.
Proposed documentation for C<state>
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=begin pod | |
C<state> declares lexically scoped variables, just like C<my>. However, | |
initialization happens exactly once the first time the initialization | |
is encountered in the normal flow of execution. Thus, state variables | |
will retain their value across multiple executions of the enclosing | |
block or routine. | |
Therefore, the subroutine | |
=begin code | |
sub a { | |
state @x = 1, 1; | |
@x.push(1, 1) | |
} | |
=end code | |
will continue to append each time it is called. So, | |
=begin code | |
say a; | |
say "next"; | |
say a; | |
say "next"; | |
say a; | |
=end code | |
will output | |
=begin code | |
[1 1 1 1] | |
next | |
[1 1 1 1 1 1] | |
next | |
[1 1 1 1 1 1 1 1] | |
=end code | |
Also, just like C<my>, declaring multiple variables must be placed in | |
parentheses and for declaring a single variable, parentheses may be | |
omitted. Within a parenthesized list, C<$> can be used as a dummy | |
placeholder. | |
In fact, C<$> can be used as an anonymous state variable without an explicit C<state> declaration. | |
=begin code | |
perl6 -e 'sub foo() { say ++$ }; foo() for ^3' | |
=end code | |
produces | |
=begin code | |
1 | |
2 | |
3 | |
=end code | |
Furthermore, state variables are not required to exist in | |
subroutines. You could, for example, use C<$> in a one-liner to | |
number the lines in a file. | |
=begin code | |
perl6 -ne 'say ++$ ~ " $_"' example.txt | |
=end code | |
Finally, if you were to use multiple anonymous state variables, they would | |
fuction independently. | |
=begin code | |
perl6 -e '{ say ++$; say ++$ } for ^5' | |
=end code | |
would produce | |
=begin code | |
1 | |
1 | |
2 | |
2 | |
3 | |
3 | |
4 | |
4 | |
5 | |
5 | |
=end pod |
Updated gist to cover the issues noted.
Excellent! The only thing I would change would be the first example using different numbers for the initialization versus the subsequent pushes. dha++
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm not sure of the official terminological distinction between blocks and closures, but let's say a "source block" is a chunk of source code and its enclosing pair of braces and a "run-time block" is the executabble equivalent at run-time. Then one needs to be aware that, while there's usually a 1-to-1 correspondence, that's not always the case -- there can be multiple run-time copies of the same source block in some scenarios. Examples:
This is called "closure cloning" in http://design.perl6.org/S04.html. (Note, this is not the same as other forms of cloning such as object cloning.) Probably gets especially interesting in a multi-threaded context.
I don't think a dummy placeholder is a state variable. I don't think that bit belongs on this page.
Not just in subroutines but in any code where a state variable is valid:
perl6 -e 'say ++$ for ^2'
I think this deserves its own subhead ("Anonymous state variables") or somesuch.