Created
October 27, 2015 21:01
-
-
Save peschwa/cb8f5e954ba932e15c31 to your computer and use it in GitHub Desktop.
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
use nqp; | |
my class WriteOnceAttribute is Attribute { | |
has Mu $!type; | |
method compose(Mu $package) { | |
# Generate accessor method, if we're meant to have one. | |
if self.has_accessor { | |
my str $name = nqp::unbox_s(self.name); | |
my $meth_name := nqp::substr($name, 2); | |
unless $package.^declares_method($meth_name) { | |
my $dcpkg := nqp::decont($package); | |
my $meth; | |
my int $attr_type = nqp::objprimspec($!type); | |
if self.rw { | |
$meth := nqp::p6bool(nqp::iseq_i($attr_type, 0)) | |
?? | |
method (Mu:D \fles:) is raw { | |
state $written = False; | |
if !$written { | |
$written = True; | |
nqp::getattr(nqp::decont(fles), $dcpkg, $name) | |
} | |
else { | |
return nqp::getattr(nqp::decont(fles), $dcpkg, $name) | |
} | |
} | |
!! | |
nqp::p6bool(nqp::iseq_i($attr_type, 1)) | |
?? | |
method (Mu:D \fles:) is raw { | |
state $written = False; | |
if !$written { | |
$written = True; | |
nqp::getattrref_i(nqp::decont(fles), $dcpkg, $name) | |
} | |
else { | |
return nqp::getattr(nqp::decont(fles), $dcpkg, $name) | |
} | |
} | |
!! | |
nqp::p6bool(nqp::iseq_i($attr_type, 2)) | |
?? | |
method (Mu:D \fles:) is raw { | |
state $written = False; | |
if !$written { | |
$written = True; | |
nqp::getattrref_n(nqp::decont(fles), $dcpkg, $name) | |
} | |
else { | |
return nqp::getattr(nqp::decont(fles), $dcpkg, $name) | |
} | |
} | |
!! | |
method (Mu:D \fles:) is raw { | |
state $written = False; | |
if !$written { | |
$written = True; | |
nqp::getattrref_s(nqp::decont(fles), $dcpkg, $name) | |
} | |
else { | |
return nqp::getattr(nqp::decont(fles), $dcpkg, $name) | |
} | |
} | |
} else { | |
nextsame; | |
} | |
$meth.set_name($meth_name); | |
$package.^add_method($meth_name, $meth); | |
} | |
} | |
# Apply any handles trait we may have. | |
self.apply_handles($package); | |
} | |
} | |
my module EXPORTHOW { } | |
EXPORTHOW.WHO<class-attr> = WriteOnceAttribute; | |
###### | |
$ cat test.pl | |
use WriteOnceAttribute; | |
class A { | |
has $.foo is rw; | |
} | |
my A $a .= new; | |
$a.foo = 5; | |
say $a.foo; | |
$a.foo = 10; | |
say $a.foo; | |
###### | |
$ ./perl6-m -I. test.pl | |
5 | |
Cannot assign to a readonly variable or a value | |
in block <unit> at test.pl:10 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment