use v6-alpha;
use Test;
plan 16;
# L<S04/"The Relationship of Blocks and Declarations" /There is a new state declarator that introduces/>
# state() inside subs
{
sub inc () {
state $svar;
$svar++;
return $svar;
};
is(inc(), 1, "state() works inside subs (#1)");
is(inc(), 2, "state() works inside subs (#2)");
is(inc(), 3, "state() works inside subs (#3)");
}
# state() inside coderefs
{
my $gen = {
# Note: The following line is only executed once, because it's equivalent
# to
# state $svar will first { 42 };
# See L<S04/"Closure traits" /emantics to any initializer, so this also works/>
state $svar = 42;
my $ret = { $svar++ };
};
my $a = $gen(); # $svar == 42
$a(); $a(); # $svar == 44
my $b = $gen(); # $svar == 44
is $b(), 44, "state() works inside coderefs";
}
# state() inside for-loops
{
for 1,2,3 -> $val {
state $svar;
$svar++;
# Only check on last run
if $val == 3 {
is $svar, 3, "state() works inside for-loops";
}
}
}
# state will first {...}
{
my ($a, $b);
eval '
my $gen = {
state $svar will first { 42 };
-> { $svar++ };
}
$a = $gen(); # $svar == 42
$a(); $a(); # $svar == 44
$b = $gen()(); # $svar == 44
';
is $b, 44, 'state will first {...} works', :todo<feature>;
}
# Return of a reference to a state() var
{
my $gen = {
state $svar = 42;
\$svar;
};
my $svar_ref = $gen();
$$svar_ref++; $$svar_ref++;
my $svar_ref = $gen();
is $$svar_ref, 44, "reference to a state() var", :todo<bug>;
}
# Anonymous state vars
# L<"http://groups.google.de/group/perl.perl6.language/msg/07aefb88f5fc8429">
{
# XXX -- currently this is parsed as \&state()
my $gen = eval '{ try { \state } }';
$gen //= sub { my $x; \$x };
my $svar_ref = $gen(); # $svar == 0
try { $$svar_ref++; $$svar_ref++ }; # $svar == 2
my $svar_ref = $gen(); # $svar == 2
is try { $$svar_ref }, 2, "anonymous state() vars", :todo<feature>;
}
# L<"http://www.nntp.perl.org/group/perl.perl6.language/20888">
# ("Re: Declaration and definition of state() vars" from Larry)
{
my ($a, $b);
eval '
my $gen = {
(state $svar) = 42;
my $ret = { $svar++ };
};
$a = $gen(); # $svar == 42
$a(); $a(); # $svar == 44
$b = $gen()(); # $svar == 42
';
is $b, 42, "state() and parens"; # svar == 43
}
# state() inside regular expressions
{
my $str = "abc";
my $re = {
# Perl 5 RE, as we don't want to force people to install Parrot ATM. (The
# test passes when using the Perl 6 RE, too.)
$str ~~ s:Perl5/^(.)/{
state $svar;
++$svar;
}/;
};
$re();
$re();
$re();
is +$str, 3, "state() inside regular expressions works";
}
# state() inside subs, chained declaration
{
sub step () {
state $svar = state $svar2 = 42;
try {
$svar++;
$svar2--;
return ($svar, $svar2);
}
};
is(step().perl, "(43, 41)", "chained state (#1)", :todo<bug>);
is(step().perl, "(44, 40)", "chained state (#2)", :todo<bug>);
}
# state in cloned closures
{
for <first second> {
my $code = {
state $foo = 42;
++$foo;
};
is $code(), 43, "state was initialized properly ($_ time)";
is $code(), 44, "state keeps its value across calls ($_ time)";
}
}