Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Mouse CPAN distribution.

Report information
The Basics
Id: 44652
Status: resolved
Priority: 0/
Queue: Mouse

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

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



Subject: Want to change what accessors to return $self on set
Test::Builder2 wants to work like this: my $result = $Builder->ok(1 + 1, "Simple addition") ->todo("Oh god, everything is so broken!"); Which is shorthand for this: my $result = $Builder->ok(1 + 1, "Simple addition"); $result->todo("Oh god, everything is so broken"); This means the todo() accessor, when setting, has to return back $self, not the new value. There doesn't appear to be any way to do this in Mouse, so I had to stop using it for Test::Builder2::Result and that sucked. http://github.com/schwern/test-more/commit/4977dbfdd79266d83ab3bf53bd91d3f09cd3a2b0 I normally don't like this style, but it solves a bunch of design problems in this case. I know plenty of others do like this style. It sucks that using or not using Mouse hinges on that decision. Can there be a flag to has() or something to change the return style of accessors? Or is there another elegant work around?
Hey Schwern, On Sun Mar 29 10:52:02 2009, MSCHWERN wrote: Show quoted text
> Test::Builder2 wants to work like this: > > my $result = $Builder->ok(1 + 1, "Simple addition") > ->todo("Oh god, everything is so broken!"); > > [...] Can > there > be a flag to has() or something to change the return style of > accessors? > Or is there another elegant work around?
Since Mouse shouldn't support any features Moose does not (so we maintain upwards compatibility), this is actually a Moose feature request. I'm not sure that such a beast would be added; we tend to do that sort of thing in the MooseX namespace. Knowing what I know about your particular case, requiring a MouseX would kinda suck. Until now I had no good solution for your problem, which is why I didn't respond. However, someone answering a question in #moose made me realize that answer is applicable to you too. You can use method modifiers on generated accessors. You could "around" your setters so that they return $self instead of the new value: around 'todo', 'skip', 'etc' => sub { my $accessor = shift; # coderef for "next tmethod", your generated attribute my $self = shift; return $self->$accessor if @_ == 0; # getter $self->$accessor(@_); # setter return $self; # return $self instead of new value }; Alternatively, you can write your own accessors, which would be end up being faster than the indirection of a method modifier. You would just have to be a little more careful to make sure your "has" isn't lying (such as by declaring your attribute "lazy" but not having lazy semantics in your custom accessor). Either answer would probably be preferable over just abandoning Mouse. :) Shawn
Subject: Re: [rt.cpan.org #44652] Want to change what accessors to return $self on set
Date: Wed, 22 Apr 2009 13:17:28 -0700
To: bug-Mouse [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Shawn M Moore via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=44652 > > > Hey Schwern, > > On Sun Mar 29 10:52:02 2009, MSCHWERN wrote:
>> Test::Builder2 wants to work like this: >> >> my $result = $Builder->ok(1 + 1, "Simple addition") >> ->todo("Oh god, everything is so broken!"); >> >> [...] Can >> there >> be a flag to has() or something to change the return style of >> accessors? >> Or is there another elegant work around?
> > Since Mouse shouldn't support any features Moose does not (so we > maintain upwards compatibility), this is actually a Moose feature > request. I'm not sure that such a beast would be added; we tend to do > that sort of thing in the MooseX namespace. Knowing what I know about > your particular case, requiring a MouseX would kinda suck. > > Until now I had no good solution for your problem, which is why I > didn't respond. However, someone answering a question in #moose made me > realize that answer is applicable to you too. You can use method > modifiers on generated accessors. You could "around" your setters so > that they return $self instead of the new value: > > around 'todo', 'skip', 'etc' => sub { > my $accessor = shift; # coderef for "next tmethod", your generated > attribute > my $self = shift; > > return $self->$accessor if @_ == 0; # getter > > $self->$accessor(@_); # setter > > return $self; # return $self instead of new value > }; > > Alternatively, you can write your own accessors, which would be end up > being faster than the indirection of a method modifier. You would just > have to be a little more careful to make sure your "has" isn't lying > (such as by declaring your attribute "lazy" but not having lazy > semantics in your custom accessor). > > Either answer would probably be preferable over just abandoning > Mouse. :)
What I wound up doing is writing my own wrappers. for my $key (@attributes) { my $accessor = "_${key}_accessor"; has $accessor => is => 'rw', init_arg => $key; # Mouse accessors can't be changed to return itself on set. my $code = sub { my $self = shift; if( @_ ) { $self->$accessor(@_); return $self; } return $self->$accessor; }; # A public one which may be overriden. __PACKAGE__->_alias($key => $code) unless defined &{$key}; } -- 29. The Irish MPs are not after "Me frosted lucky charms". -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
This seems to have resolved itself. I'm closing this bug now for accounting purposes.