: sub foo() {
: has $s //= 0; : $s ++ ;
: }
: : print foo, foo, foo;
This is interesting, but I think it would be a mistake to give C<has> two unrelated meanings -- and I think we'd have to stretch our concepts of objects a little too far to consider these two meanings related. (Yes, *I* can easily stretch my mind to envisage the "attributes of a subroutine", but should everyone else have to?)
Futhermore, this approach opens another vermiferous can. I would argue that C<//=> is the wrong way to initialize it, since that effectively prevents C<undef> values from being used with such variables.
Curiously we have already felt the lack of an assign-on-non-existence initializer elsewhere...for optional parameters. Perhaps we have not yet have gone far enough in mirroring the various levels of reality that a value can aspire to:
Function Assign unless...
true ||= defined //= exists hmmmmmmmm
One is almost tempted by something like C<??=>. Well, almost.
But back to the topic of discussion. I have argued for some considerable time that this "static variable" *functionality* is extremely useful and much tidier than the current alternative:
{ my $s = 0; sub foo() { $s++; } }
But using Yet Another Declarator is, I believe, the wrong approach.
The variable $s is a regular lexical variable in every respect, save one: it has the unusual trait that is retained from call to call of its surrounding code.
Hence, I would argue, one ought to simply mark it with a trait:
sub foo() { my $s is retained = 0; $s++; }
Other possible trait names:
is kept is preserved is permanent is reused is saved is stored is restored is irrepressible
Yes, the names are all considerably longer than a C<has> declarator, but I see that as a bonus. Persistent behaviour by a lexical is unusually enough that it ought to be loudly and clearly marked.
Oh, and note that I very deliberately did not suggest C<is static>!
Damian