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: 56523
Status: resolved
Priority: 0/
Queue: Mouse

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

Bug Information
Severity: Important
Broken in: 0.53
Fixed in: (no value)



Subject: has with reader, writer, lazy and builder cannot create a write-only accessor
The following code works in Moose and Mouse 0.52 but fails in 0.53. package Foo; use Mouse; has history => ( reader => 'history', writer => 'set_history', builder => '_build_history', lazy => 1, ); __END__ syntax error at wo-accessor for history (lib/Mouse/Meta/Method/Accessor.pm) line 5, near "} elsif" This is the code which is generated: package Foo; #line 1 "wo-accessor for history (lib/Mouse/Meta/Method/Accessor.pm)" sub { if(@_ < 2){ Carp::confess("Not enough arguments for the writer of history") }{ return $_[0]->{q{history}} = $_[1]; } elsif(!exists $_[0]->{q{history}}){ $_[0]->{q{history}} = $_[0]->$builder(); } return $_[0]->{q{history}}; } If you tidy that up it becomes clear: package Foo; #line 1 "wo-accessor for history (lib/Mouse/Meta/Method/Accessor.pm)" sub { if(@_ < 2){ Carp::confess("Not enough arguments for the writer of history") } { return $_[0]->{q{history}} = $_[1]; } elsif(!exists $_[0]->{q{history}}){ $_[0]->{q{history}} = $_[0]->$builder(); } return $_[0]->{q{history}}; } I think it's incorrect for the builder code to exist in the wo-accessor.
This appears to only be a problem in the pure Perl implementation.
Attached is a patch to fix it. It simply doesn't put the builder code into a write-only accessor. I don't know why the change from 0.52 to 0.53 broke this.
Subject: mouse.patch
diff --git a/lib/Mouse/Meta/Method/Accessor.pm b/lib/Mouse/Meta/Method/Accessor.pm index 670d721..f7f75cb 100755 --- a/lib/Mouse/Meta/Method/Accessor.pm +++ b/lib/Mouse/Meta/Method/Accessor.pm @@ -75,7 +75,7 @@ sub _generate_accessor_any{ $class->throw_error("Unknown accessor type '$type'"); } - if ($attribute->is_lazy) { + if ($attribute->is_lazy and $type ne 'wo') { my $value; if (defined $builder){ @@ -88,7 +88,7 @@ sub _generate_accessor_any{ $value = '$default'; } - $accessor .= "els" if $type eq 'rw' || $type eq 'wo'; + $accessor .= "els" if $type eq 'rw'; $accessor .= "if(!exists $slot){\n"; if($should_coerce){ $accessor .= "$slot = \$constraint->coerce($value)"; diff --git a/t/builder_writer.t b/t/builder_writer.t new file mode 100644 index 0000000..0a417f5 --- /dev/null +++ b/t/builder_writer.t @@ -0,0 +1,37 @@ +#!/usr/bin/perl + +use Test::More; + +{ + package Foo; + + use Mouse; + + has thing => ( + reader => 'thing', + writer => 'set_thing', + builder => '_build_thing', + lazy => 1, + ); + + sub _build_thing { + 42; + } +} + +# Get them set +{ + my $obj = Foo->new; + is $obj->thing, 42; + $obj->set_thing( 23 ); + is $obj->thing, 23; +} + +# Set then get +{ + my $obj = Foo->new; + $obj->set_thing(23); + is $obj->thing, 23; +} + +done_testing();
Hi, Michael. Thank you for your patch. I have released 0.54 with it. I think it is not in 0.53, but in older versions. Anyway, tests are included. By the way, if you have distributions that use Mouse, please tell me these name. Mouse has a set of tests for external modules which depend on Mouse(*). * http://cpansearch.perl.org/src/GFUJI/Mouse-0.53/t/800_with_external/002-externals.t Regards, ---- gfx
Subject: Re: [rt.cpan.org #56523] has with reader, writer, lazy and builder cannot create a write-only accessor
Date: Sat, 17 Apr 2010 13:58:27 +0300
To: bug-Mouse [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
Goro Fuji via RT wrote: Show quoted text
> Thank you for your patch. I have released 0.54 with it. > I think it is not in 0.53, but in older versions. Anyway, tests > are included.
Thanks! Show quoted text
> By the way, if you have distributions that use Mouse, please tell me > these name. Mouse has a set of tests for external modules which depend > on Mouse(*).
Test::Builder2, which will eventually back Test::Builder, Test::More and pretty much every Test module, depends on Mouse, but it hasn't been released. You can find it in this branch. http://github.com/schwern/test-more/tree/Test-Builder2 It uses its own copy of Mouse so as to not set up a circular dependency and to provide stability. It copies blib/lib/Mouse into lib/Test/Builder2/Mouse and then replaces all instances of "Mouse" with "Test::Builder2::Mouse" or "Test/Builder2/Mouse" as appropriate. So Test::Builder2 actually uses Test::Builder2::Mouse. You can see the script it uses to do that transformation here: http://github.com/schwern/test-more/blob/Test-Builder2/dist/eat_mouse Advice on how to better use Mouse is always welcome. rafl did some much needed overhauling last weekend. -- 7. Not allowed to add "In accordance with the prophesy" to the end of answers I give to a question an officer asks me. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
On Sat Apr 17 06:58:42 2010, schwern@pobox.com wrote: Show quoted text
> > By the way, if you have distributions that use Mouse, please tell me > > these name. Mouse has a set of tests for external modules which
> depend
> > on Mouse(*).
> > Test::Builder2, which will eventually back Test::Builder, Test::More > and > pretty much every Test module, depends on Mouse, but it hasn't been > released. > You can find it in this branch. > http://github.com/schwern/test-more/tree/Test-Builder2
Hmm, testing unreleased modules is difficult. Well, I'll think it later. Show quoted text
> > It uses its own copy of Mouse so as to not set up a circular > dependency and to > provide stability. It copies blib/lib/Mouse into > lib/Test/Builder2/Mouse and > then replaces all instances of "Mouse" with "Test::Builder2::Mouse" or > "Test/Builder2/Mouse" as appropriate. So Test::Builder2 actually uses > Test::Builder2::Mouse. You can see the script it uses to do that > transformation here: > http://github.com/schwern/test-more/blob/Test-Builder2/dist/eat_mouse > > Advice on how to better use Mouse is always welcome. rafl did some > much > needed overhauling last weekend.
Looks great. Mouse::Tiny is maintained for that purpose, which makes embedding easier, possibly. -- Goro Fuji (gfx) GFUJI at CPAN.org