Here is a quickly hacked together example:

multi trait_mod:<is> (Attribute:D $a, :$xmlattr!) {
    my $mname = $a.name.substr(2);
    my &method = my method { say "ATTR($mname):", my \val = $a.get_value(self); 
val };
    &method.set_name($mname);
    $a.package.^add_method($mname, &method);
}

class Foo {
    has $.foo is xmlattr;
}

say Foo.new(foo => 42).foo;


It would output:

ATTR(foo):42
42

Best regards,
Vadim Belman

> On Sep 8, 2019, at 8:59 PM, Mark Devine <m...@markdevine.com> wrote:
> 
> Vadim,
>  
> Vadim,
>  
> Would you be able to expand on how to implement the trait that wraps into 
> what is effectively the ‘get_value’ accessor of an attribute?  I’m not 
> finding enough in the documentation to connect the dots.  I’ve looked at 
> XML::Class, which does some pretty heavy trait’ing, but my intuition has 
> expired.
>  
> my role XML-attribute {
>     has $attr;
>     method get_value () {
>         say 'in XML-attribute method get_value with ' ~ $.name;
>         $attr;
>     }
>     method set_value ($) {      
>         say 'in XML-attribute method set_value with ' ~ $.name;
>         $attr = $;
>     }
> }
>  
> multi sub trait_mod:<is> (Attribute $a, :$xmlattr) {
>     say "⟨is xmlattr⟩ has been called with ⟨$xmlattr⟩ on {$a.WHICH}";
>     $a does XML-attribute;
> }
>  
> class System {
>     has Str $.SerialNumber is xmlattr;
> }
>  
> say System.new(:SerialNumber('ABCDEFG')).SerialNumber;
>  
>  
> I’ve twisted myself into a pretzel.  I couldn’t even find where a role gets 
> ‘$’, but I saw it in JSTOWE’s code so I mimicked.
>  
> I need a little more broad-based help on what goes where and when.
>  
> Thanks,
>  
> Mark
>  
> From: Vadim Belman <vr...@lflat.org> 
> Sent: Sunday, September 8, 2019 14:57
> To: Mark Devine <m...@markdevine.com>
> Cc: perl6-users <perl6-us...@perl.org>
> Subject: Re: Wrap an attribute’s ^get_value method in TWEAK
>  
> Hi Mark,
>  
> get_value won't give you what you expect. It's use is narrowly limited to 
> trait 'is handles' and method .perl. Besides, are you sure all of your 
> attributes will be considered as belonging to XML? I mean, won't there be 
> need for utility attributes serving exclusively internal needs of a class? If 
> so, then the best solution is to create a trait for an attribute and have it 
> like:
>  
> has $.SerialNumber is xmlattr;
>  
> The trait would then install an accessor which would do what you need.
>  
> Best regards,
> Vadim Belman 
> 
> 
> On Sep 8, 2019, at 12:41 PM, Mark Devine <m...@markdevine.com 
> <mailto:m...@markdevine.com>> wrote:
>  
> Perl6 Community,
>  
> How do I properly wrap an attribute’s ^get_value method in TWEAK?  If a 
> condition exists, I’d like to wrap all (:local) attributes so that they can 
> do some extra work.
>  
> The module that I’m working on has classes/attributes for hundreds of fields 
> in dozens of different, big XML files -- there’s a lot.  And XML is easily 
> extended, so I may very well be adding hundreds more attributes in the 
> future.  I would very much prefer to preserve the automatic accessor behavior 
> of ‘has $.attr;’ versus writing a billion set/get accessors myself – truly 
> prohibitive.  Wrapping seems the elegant/extensible approach.
>  
> class System {
>     has $.SerialNumber;
>     submethod TWEAK {
>         for self.^attributes(:local) -> $attr {
>             self.$attr.^get_value.wrap: { say 'in ' ~ $attr.name ~ "'s 
> get_value"; nextsame; };
>         }
>         self;
>     }
> }
> say System.new(:SerialNumber('ABCDEFG')).SerialNumber;
>  
> # OUTPUT: No such method 'CALL-ME' for invocant of type 'Attribute'
>  
> I know the above .wrap is probably misguided, but it sort of demonstrates 
> what I’m trying to do.
>  
> I’m not finding the proper approach.  Any hints?  Any tutorials?  Any 
> existing examples in the ecosystem that I could mimic?
>  
> Thanks,
>  
> Mark

Reply via email to