Skip to content

Instantly share code, notes, and snippets.

@zoffixznet
Created November 26, 2016 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zoffixznet/21fff132bdacee9682025c195ed2e2fe to your computer and use it in GitHub Desktop.
Save zoffixznet/21fff132bdacee9682025c195ed2e2fe to your computer and use it in GitHub Desktop.
my %class-info;
multi sub trait_mod:<is>(Attribute:D $attr, :$handled [:$setter=True,:$getter=True])
{
my $class=$attr.package;
my $name=$attr.name.substr(2);
return if defined %class-info{$class.^name}{$name};
%class-info{$class.^name}{$name}=True;
say ($attr.name=>$name,$attr,$class.^attributes(:local)>>.name).perl;
my %accessors=(setter=>$setter,getter=>$getter);
my method handler(Any:D $self: |c)
{
if c.Bool
{
if %accessors<setter>.isa(Bool)
{
$attr.set_value($self,|c);
return $self;
}
elsif %accessors<setter>.isa(Str)
{
return $self."%accessors<setter>"(|c);
}
elsif %accessors<setter>.isa(Method)
{
$self.&%accessors<setter>(|c);
}
else
{
die "Invalid type %accessors<setter>.^name of setter for property $name in $class.^name";
}
}
else
{
if %accessors<getter>.isa(Bool)
{
return $attr.get_value($self,|c);
}
elsif %accessors<getter>.isa(Str)
{
return $self."%accessors<getter>"();
}
elsif %accessors<getter>.isa(Method)
{
return $self.&%accessors<getter>;
}
else
{
die "Invalid type %accessors<getter>.^name of getter for property $name in $class.^name";
}
}
}
$class.^add_method($name,&handler);
}
class A
{
has Str:D $!name is handled[setter=>'set_name']='unnamed';
method set_name(Str:D $name where *.trim.chars) returns ::?CLASS:D
{
put "New name: $name, old name: $!name.";
$!name=$name;
return self;
}
}
my $a=A.new;
say $a.name('Bob');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment