Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Perl 6 OOP: before and after methods "CLOS style"

by snoopy (Curate)
on Feb 19, 2017 at 21:38 UTC ( #1182319=note: print w/replies, xml ) Need Help??


in reply to Perl 6 OOP: before and after methods "CLOS style"

'before' and 'after' modifiers can be done declaratively. But may need some meta-programming extensions.

I've done a first cut at a basic solution. Module CLOS defines before and after method traits as below:

use CLOS; class Bake { method preheat { say "preheating"; } method cook { say "cooking"; } method rest { say "resting"; } } class Cook is Bake { method preheat is before { say "...about to preheat"; } method rest is after { say "...resting done"; } } my $cook = Cook.new; $cook.preheat; say "----"; $cook.cook; say "----"; $cook.rest;
Produces:
perl6 -I . Bake.pm ...about to preheat preheating ---- cooking ---- resting ...resting done
Contents of CLOS.pm follow:
This approach combines:
1. traits Traits Meta Data With Character (moritz, 2011)
2. class meta-programming Adventures in writing a simple grammar profiler (perlpilot, 2011) (adapted from grammars to classes)
3. Object hashes Object Hashes (Brian D Foy, 2016)
my class CLOSClassHOW is Metamodel::ClassHOW { my Bool %before{Any}; my Bool %after{Any}; multi sub trait_mod:<is>(Routine $r, :$before!) is export { %before{$r} = True; } multi sub trait_mod:<is>(Routine $r, :$after!) is export { %after{$r} = True; } #| find this method in our parents method !find-super-method($obj, $name, *@etc) { my @mro = self.mro($obj); @mro.shift; # skip ourselves for @mro { my %methods = $_.HOW.method_table($_); return %methods{$name} if %methods{$name}:exists; } } method find_method($obj, $name) { my $raw-meth := callsame; my $meth := $raw-meth; if $raw-meth.defined && (%before{$raw-meth} || %after{$raw-met +h}) { my $next-meth := self!find-super-method($obj,$name); $meth := -> $c, |args { $raw-meth($obj, |args) if %before{$raw-meth}; my $result := $next-meth($obj, |args) if $next-meth.defined ; $raw-meth($obj, |args) if %after{$raw-meth}; $result; } } $meth; } method publish_method_cache($obj) { # no caching, so we always hit find_method } } my module EXPORTHOW { } EXPORTHOW.WHO.<class> = CLOSClassHOW;
Basically we define traits before and after which collect the routines to be wrapped in object hashes %before and %after. The ClassHOW meta-class is extended to interpret the `before` and after traits, invoking a super method located with the !find-super-method private method.
This could possibly be fleshed out into a Perl 6 module.

Replies are listed 'Best First'.
Re^2: Perl 6 OOP: before and after methods "CLOS style"
by adhrain (Sexton) on Feb 20, 2017 at 22:45 UTC

    Awesome!

    I didn't know the depth of metaprogramming in Perl 6, now I have pointers to many hours of study

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1182319]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2022-05-20 08:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (73 votes). Check out past polls.

    Notices?