Re: Best way of implementing "Walkmeth" in Moose
Shlomi Fish writes: > On Wednesday 28 Apr 2010 08:04:31 Daniel Pittman wrote: >> Shlomi Fish writes: >> > On Tuesday 27 Apr 2010 15:51:07 Stevan Little wrote: >> >> On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote: Sorry for taking so very long to respond to this. [...] >> > OK, thanks. I might create a small MooseX::AccumArray distro out of it. >> >> If you do get around to looking at this, I have a couple of times played >> with the idea of either hacking on Class::MOP[1], or writing an extension, >> to do some more of the method combination bits that CLOS used to do. >> >> Specifically, I have run across the need for: >> >> 'and' and 'or' method combination[2], both with most-specific-first and >> least-specific-first ordering — various validations like ACL-style >> authorisation, and data validation, benefit from those. >> >> The "accumulate to array" method combination you mention is also quite >> useful, but a bit obvious right now. >> >> CLOS also had min, max, and plus method combinations, for which I can see >> some logic exposing in Moose also — and probably some of the "...write >> your own" too. > > OK, now we're talking about generalising the walkmeth functionality of what > I need. I didn't get so far into studying CLOS (I studied CL mostly from the > book "Practical Common Lisp"), or forgot it, but I think I know what you > mean. Everything you describe is a sub-case of "reduce" like the one in > List::Util, although the concept predates List::Util and Perl itself by a > long time: Mmmm, more or less, in the same way that the standard method combination that Moose supports is also a sub-case of "reduce": they all take a list of applicable methods, then apply them in a specific order, and do something to the result. The standard method combination is more or less the "around" or "extend" case, where an explicit action is taken to go on to the next; the others do more complicated things, but mostly the same. > Now, the problem with such a reduce is that it has to know to short-circuit > in case it's a cumulative (and...) or (or...) operation. *nod* The usual implementation would be something like this for the slow-path: sub and_method_combination { my (@all_applicable_methods) = @_; sub { my ($self, @args) = @_; for my $method (@all_applicable_methods) { my $result = $self->$method(@args); return $result if $result; } return; } } That contrasts to the "standard" method combination, which calls the most specific method, and then makes arrangements so that can call the next-most-specific-method if it wants. Those are, in Moose, the 'inner/augment' and 'super/override' sugar, which wrap around the standard inheritance stuff. (CLOS unifies them: you specify "most-specific-first" or "least-specific-first" in the method combination, and it then arranges for a generic 'call-next-method' to do what 'inner' or 'super' do in Moose.) > And then we need to decide whether we code one distinct accumulating > meta-method for every such operation (as accum_array, accum_and, accum_or, > accum_min, accum_max, accum_sum, etc.) or that we implement a generic reduce > and then implement each specific accumulator based on it (which may result > in slower code.). I would hope this could be part of Class::MOP, so that you can have a nice protocol for generating "slow" path code, which is probably dynamically generated subroutines walking arrays, and "fast" path code, which dynamically install the appropriate methods. This is, incidentally, roughly what the method wrapping code used for method modifiers do — except that they don't wrap anything until you add a modifier. > And naturally I now remember that "perfect is the enemy of good", and that > there's a saying in Hebrew that "caught a lot - did not catch > anything.". Oh! Decisions, decisions. *nod* Daniel -- ✣ Daniel Pittman✉ dan...@rimspace.net☎ +61 401 155 707 ♽ made with 100 percent post-consumer electrons
Re: Best way of implementing "Walkmeth" in Moose
On Wednesday 28 Apr 2010 08:04:31 Daniel Pittman wrote: > Shlomi Fish writes: > > On Tuesday 27 Apr 2010 15:51:07 Stevan Little wrote: > >> On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote: > >> > After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have > >> > accumulated several questions about Moose, so I'd post each one in a > >> > separate post to keep each thread single-topic. (I hope it's OK.) > >> > > >> > The first one is how to implement a Class::Std/Perl 6-like walkmeth: > >> > > >> > * > >> > http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=2007070 > >> > 1 > >> > > >> > * http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE). > > > > [SNIP] > > > >> > My question is: is there a better way to do it using Moose? (Or one of > >> > the MooseX modules?) Instead, should I implement my own private logic > >> > or create a new MooseX module? > >> > >> No, that is pretty much how you would do it. Take a look at > >> Moose::Object::BUILDALL, it does the same thing. > > > > OK, thanks. I might create a small MooseX::AccumArray distro out of it. > > If you do get around to looking at this, I have a couple of times played > with the idea of either hacking on Class::MOP[1], or writing an extension, > to do some more of the method combination bits that CLOS used to do. > > Specifically, I have run across the need for: > > 'and' and 'or' method combination[2], both with most-specific-first and > least-specific-first ordering — various validations like ACL-style > authorisation, and data validation, benefit from those. > > The "accumulate to array" method combination you mention is also quite > useful, but a bit obvious right now. > > > CLOS also had min, max, and plus method combinations, for which I can see > some logic exposing in Moose also — and probably some of the "...write > your own" too. OK, now we're talking about generalising the walkmeth functionality of what I need. I didn't get so far into studying CLOS (I studied CL mostly from the book "Practical Common Lisp"), or forgot it, but I think I know what you mean. Everything you describe is a sub-case of "reduce" like the one in List::Util, although the concept predates List::Util and Perl itself by a long time: http://search.cpan.org/perldoc?List::Util Now, the problem with such a reduce is that it has to know to short-circuit in case it's a cumulative (and...) or (or...) operation. And then we need to decide whether we code one distinct accumulating meta-method for every such operation (as accum_array, accum_and, accum_or, accum_min, accum_max, accum_sum, etc.) or that we implement a generic reduce and then implement each specific accumulator based on it (which may result in slower code.). And naturally I now remember that "perfect is the enemy of good", and that there's a saying in Hebrew that "caught a lot - did not catch anything.". Oh! Decisions, decisions. Regards, Shlomi Fish > Daniel > > > Footnotes: > [1] This embeds the "standard" method combination inside > Class::MOP::Method::Wrapped as a private method internally; it doesn't > look terribly hard to extend to either use external method combination > classes, or to support non-standard (eg: not before, after, around) > decorators ... which makes me think I have missed something in my > look-but-not-touch investigation so far. > > [2] I suspect that Perl users would like a "and-true" and "and-defined" > variant of both of these, that short-circuit when the value is false > and undefined respectively, where CLOS users didn't. -- - Shlomi Fish http://www.shlomifish.org/ http://www.shlomifish.org/humour/ways_to_do_it.html God considered inflicting XSLT as the tenth plague of Egypt, but then decided against it because he thought it would be too evil. Please reply to list if it's a mailing list post - http://shlom.in/reply .
Re: Best way of implementing "Walkmeth" in Moose
Shlomi Fish writes: > On Tuesday 27 Apr 2010 15:51:07 Stevan Little wrote: >> On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote: >> > >> > After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have >> > accumulated several questions about Moose, so I'd post each one in a >> > separate post to keep each thread single-topic. (I hope it's OK.) >> > >> > The first one is how to implement a Class::Std/Perl 6-like walkmeth: >> > >> > * http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=20070701 >> > >> > * http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE). >> > > [SNIP] >> > My question is: is there a better way to do it using Moose? (Or one of >> > the MooseX modules?) Instead, should I implement my own private logic or >> > create a new MooseX module? >> >> No, that is pretty much how you would do it. Take a look at >> Moose::Object::BUILDALL, it does the same thing. > > OK, thanks. I might create a small MooseX::AccumArray distro out of it. If you do get around to looking at this, I have a couple of times played with the idea of either hacking on Class::MOP[1], or writing an extension, to do some more of the method combination bits that CLOS used to do. Specifically, I have run across the need for: 'and' and 'or' method combination[2], both with most-specific-first and least-specific-first ordering — various validations like ACL-style authorisation, and data validation, benefit from those. The "accumulate to array" method combination you mention is also quite useful, but a bit obvious right now. CLOS also had min, max, and plus method combinations, for which I can see some logic exposing in Moose also — and probably some of the "...write your own" too. Daniel Footnotes: [1] This embeds the "standard" method combination inside Class::MOP::Method::Wrapped as a private method internally; it doesn't look terribly hard to extend to either use external method combination classes, or to support non-standard (eg: not before, after, around) decorators ... which makes me think I have missed something in my look-but-not-touch investigation so far. [2] I suspect that Perl users would like a "and-true" and "and-defined" variant of both of these, that short-circuit when the value is false and undefined respectively, where CLOS users didn't. -- ✣ Daniel Pittman✉ dan...@rimspace.net☎ +61 401 155 707 ♽ made with 100 percent post-consumer electrons
Re: Best way of implementing "Walkmeth" in Moose
On Tuesday 27 Apr 2010 15:51:07 Stevan Little wrote: > On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote: > > Hi all! > > > > After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have > > accumulated several questions about Moose, so I'd post each one in a > > separate > > post to keep each thread single-topic. (I hope it's OK.) > > > > The first one is how to implement a Class::Std/Perl 6-like walkmeth: > > > > * http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=20070701 > > > > * http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE). > > [SNIP] > > My question is: is there a better way to do it using Moose? (Or one > > of the > > MooseX modules?) Instead, should I implement my own private logic or > > create a > > new MooseX module? > > No, that is pretty much how you would do it. Take a look at > Moose::Object::BUILDALL, it does the same thing. OK, thanks. I might create a small MooseX::AccumArray distro out of it. Regards, Shlomi Fish -- - Shlomi Fish http://www.shlomifish.org/ Parody on "The Fountainhead" - http://shlom.in/towtf God considered inflicting XSLT as the tenth plague of Egypt, but then decided against it because he thought it would be too evil. Please reply to list if it's a mailing list post - http://shlom.in/reply .
Re: Best way of implementing "Walkmeth" in Moose
On Apr 27, 2010, at 3:36 AM, Shlomi Fish wrote: Hi all! After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have accumulated several questions about Moose, so I'd post each one in a separate post to keep each thread single-topic. (I hope it's OK.) The first one is how to implement a Class::Std/Perl 6-like walkmeth: * http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=20070701 * http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE). What it does is that in each class out of the various inheritance tree of the module, there is a method, and one accumulates their results so if: [pseudo-code] package Base1; sub a1 { return [qw(foo)]; } package Base2; sub a1 { return [qw(bar)]; } package Class; extends('Base1', 'Base2'); sub a1 { return [qw(quux)]; } [/p-code] Then accumulating a1 will yield [qw(foo bar quux)]. I've implemented something similar in Test-Run: http://svn.berlios.de/svnroot/repos/web-cpan/Test-Harness- NG/trunk/modules/Test-Run/lib/Test/Run/Base.pm (short URL - http://xrl.us/bhjhgt ). Quoting from it: [code] sub accum_array { my ($self, $args) = @_; my $method_name = $args->{method}; # my $class = ((ref($self) eq "") ? $self : ref($self)); my @results; foreach my $isa_class ( $self->meta->find_all_methods_by_name($method_name) ) { my $body = $isa_class->{code}->body(); push @results, @{ $self->$body() }; } return \...@results; } [/code] My question is: is there a better way to do it using Moose? (Or one of the MooseX modules?) Instead, should I implement my own private logic or create a new MooseX module? No, that is pretty much how you would do it. Take a look at Moose::Object::BUILDALL, it does the same thing. - Stevan
Best way of implementing "Walkmeth" in Moose
Hi all! After merging XML-Grammar-Fiction and XML-Grammar-Screenplay, I have accumulated several questions about Moose, so I'd post each one in a separate post to keep each thread single-topic. (I hope it's OK.) The first one is how to implement a Class::Std/Perl 6-like walkmeth: * http://blog.gmane.org/gmane.comp.lang.perl.qotw.discuss/month=20070701 * http://search.cpan.org/perldoc?Class::Std (search for CUMULATIVE). What it does is that in each class out of the various inheritance tree of the module, there is a method, and one accumulates their results so if: [pseudo-code] package Base1; sub a1 { return [qw(foo)]; } package Base2; sub a1 { return [qw(bar)]; } package Class; extends('Base1', 'Base2'); sub a1 { return [qw(quux)]; } [/p-code] Then accumulating a1 will yield [qw(foo bar quux)]. I've implemented something similar in Test-Run: http://svn.berlios.de/svnroot/repos/web-cpan/Test-Harness- NG/trunk/modules/Test-Run/lib/Test/Run/Base.pm (short URL - http://xrl.us/bhjhgt ). Quoting from it: [code] sub accum_array { my ($self, $args) = @_; my $method_name = $args->{method}; # my $class = ((ref($self) eq "") ? $self : ref($self)); my @results; foreach my $isa_class ( $self->meta->find_all_methods_by_name($method_name) ) { my $body = $isa_class->{code}->body(); push @results, @{ $self->$body() }; } return \...@results; } [/code] My question is: is there a better way to do it using Moose? (Or one of the MooseX modules?) Instead, should I implement my own private logic or create a new MooseX module? Regards, Shlomi Fish -- - Shlomi Fish http://www.shlomifish.org/ http://www.shlomifish.org/humour/ways_to_do_it.html God considered inflicting XSLT as the tenth plague of Egypt, but then decided against it because he thought it would be too evil. Please reply to list if it's a mailing list post - http://shlom.in/reply .