Skip Menu |

This queue is for tickets about the Moo CPAN distribution.

Report information
The Basics
Id: 82809
Status: rejected
Priority: 0/
Queue: Moo

People
Owner: Nobody in particular
Requestors: FGA [...] cpan.org
Cc: ether [...] cpan.org
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 1.000007
Fixed in: (no value)



Subject: Moo should provide a public function to turn arguments into canonical form
The default behavior of Moo is to turn (foo => 'bar') into { foo => 'bar' } through the default BUILDARGS in Moo::Object. Users of distributions based on Moo probably get used to being able to write ->new(foo => 'bar') or ->new({ foo => 'bar' }) at their convenience, so it makes sense to be able to do that with regular methods as well. As soon as you start writing custom BUILDARGS methods though, or using parameter validation modules, you need to replicate this functionality by hand (or in the case of a custom BUILDARGS, you can try running SUPER::BUILDARGS but that's iffy at best since it relies on implementation details). A better alternative would be to have something like: use Moo qw/canonicalize_arguments/; sub reticulate_splines { my $self = shift; my $params = canonicalize_arguments(@_); # now reticulate your splines, confident in the fact that whatever # the user passed, $params is a hashref } except with a function name that doesn't suck.
Subject: Re: [rt.cpan.org #82809] Moo should provide a public function to turn arguments into canonical form
Date: Fri, 18 Jan 2013 10:31:41 -0800
To: Fabrice Gabolde via RT <bug-Moo [...] rt.cpan.org>
From: Karen Etheridge <ether [...] cpan.org>
On Fri, Jan 18, 2013 at 11:15:38AM -0500, Fabrice Gabolde via RT wrote: Show quoted text
> The default behavior of Moo is to turn (foo => 'bar') into { foo => > 'bar' } through the default BUILDARGS in Moo::Object. Users of > distributions based on Moo probably get used to being able to write > ->new(foo => 'bar') or ->new({ foo => 'bar' }) at their convenience, so > it makes sense to be able to do that with regular methods as well.
This should be ported to Moose as well. I occasionally need to do something like: around BUILDARGS => sub { my $orig = shift; my $class = shift; # first, convert hash to hashref my $params = Moose::Object::BUILDARGS($class, @_); ...now operate on $params some more... }; ...because calling $class->$orig($@) directly would call some other extensions that I don't want to call yet (because I want to alter $params first before they see them - e.g. MooseX::Constructor::AllErrors, or MooseX::UndefTolerant, etc). Being able to canonicalize first without having to call Moose::Object::BUILDARGS itself (allowing me to call $orig later, say at the end of the method modification) would be much cleaner. If a consensus arises around the name of this method etc, I'd be happy to do the Moose work. You can harass me on irc any time.
On Fri, 18 Jan 2013 13:31:55 -0500, ETHER wrote: Show quoted text
> This should be ported to Moose as well.
That's a good point. Actually blessed-hashref-based classes would benefit from this as well (I'm thinking of me here as most of my work-related modules are Moo(?:se)?-less). Actually everybody would... Maybe this should go in a tiny module, like Scalar::Listify does for the web developers' "turn this scalar/list/arrayref into an arrayref" canonicalization. (The one you have to perform every time you get a value from an HTML form since you can't differentiate between a multi-valued parameter that only has one value set, and a single-valued parameter, in the general case.) It's really very little code for a standalone module, so maybe I'm just too fixated on not duplicating code. Show quoted text
> If a consensus arises around the name of this method etc, I'd be > happy to do the Moose work. You can harass me on irc any time.
I actually don't like my original "canonicalize_arguments" because the "canonical" part is subjective and there's nothing specific to function arguments in there. "hashify" sounds silly but it goes well with the established "listify". No other ideas at the moment, good function names are hard...
On Sat Jan 19 05:15:54 2013, FGA wrote: Show quoted text
> I actually don't like my original "canonicalize_arguments" because the > "canonical" part is subjective and there's nothing specific to > function arguments in there.
I've chatted with mst a bit. He pointed out quite properly that the canonicalization of arguments is precisely what BUILDARGS is meant to do, so if anything should be pulled out of there, it's the *rest* of the logic - parameter validation etc. What usecases do you have where you need to replicate the canonicalization process yourself? What we should do is find a different place to hook your logic into, that is run *after* BUILDARGS, not in it.
On Sat, 19 Jan 2013 12:56:41 -0500, ETHER wrote: Show quoted text
> I've chatted with mst a bit. He pointed out quite properly that the > canonicalization of arguments is precisely what BUILDARGS is meant > to do, so if anything should be pulled out of there, it's the *rest* > of the logic - parameter validation etc.
That's true. I'm trying to work out what I meant and what I wanted last week, actually. I filed the issue rather late in the day just before getting off work... I had several use cases in mind then but after the week-end I can't think of one that wouldn't be better handled somewhere else (BUILD, alternative new_from_foo class methods, coercions...). You can mark the issue as "rejected" if you wish. (Now I'm confused. When do you guys need to override BUILDARGS?)
Show quoted text
> (Now I'm confused. When do you guys need to override BUILDARGS?)
It's not uncommon for a class to want to munge the args before the constructor ever sees them - for example to translate one form of an argument to another (although this can be done with coercion in a type constraint, sometimes it's easier to do it here)... also some extensions hook into BUILDARGS to further modify the arg list, or to perform extra verifications on it, before the normal type checking kicks in. But we should examine each of these cases individually and think about where better to hook into Moo/Moose guts to accomplish these goals.