Re: make_immutable bug?

[email protected] ("woosley. xu.")
Newsgroups perl.moose
Message-ID <CAG6tKJO0w3Fc5BDobOeDgt0N8mFjy6kCTbhc1qD9-_RzXa+Jcw@mail.gmail.com>
The output of your code on my computer is:

Useless use of reference constructor in void context at /home/ezhouxu/test/
t.pl line 11.
not ok 1 - So far so good
#   Failed test 'So far so good'
#   at /home/ezhouxu/test/t.pl line 19.
#          got: '2'
#     expected: '4'
not ok 2 - Not so good - returns 12
#   Failed test 'Not so good - returns 12'
#   at /home/ezhouxu/test/t.pl line 21.
#          got: '3'
#     expected: '6'
not ok 3 - Really not so good, now returns 8!
#   Failed test 'Really not so good, now returns 8!'
#   at /home/ezhouxu/test/t.pl line 22.
#          got: '2'
#     expected: '4'
1..3
# Looks like you failed 3 tests of 3.

Shell returns 3

but I think I got your point. So basically even if I run
meta->make_immutable on an constructed object, it is applied to the whole
__CLASS__, not just the object.

What I want to do is to 'with' different Roles depending on the user
arguments passed to 'new' constructor, and then make the object immutable.
is that possible?




2011/12/1 Tomas Doran <[email protected]>

>
> On 1 Dec 2011, at 08:42, woosley. xu. wrote:
>
>  Hi all,
>>   Is this a Moose make_immutable bug?
>>
>
> No.
>
>
>  package b;
>> use Moose;
>> around 'BUILDARGS' => sub {
>>   my $orig = shift;
>>   my $self = shift;
>>
>
> This happens at object construction time! Meaning you will apply the 'a'
> role once for every object you ever construct. (Meaning method modifiers
> will apply N times, where N is number of objects you've constructed).
>
>
>    with 'a';
>>   $self->$orig;
>> };
>> sub BUILD {
>>   my $self  = shift;
>>   $self->meta->make_immutable;
>> }
>>
>
>
> So what happens is that the first object creation adds the role to the
> _class_, and then makes the _class_ immutable.
>
> The second object you construct then tries to add the role to the class
> (again), and this fails - as the class is immutable.
>
> You really really don't want to be having class-wide effects whenever you
> construct an instance of the class, and make immutable telling you that
> you're doing something insane is absolutely correct here.
>
> Consider:
>
> package Double;
> use Moose::Role;
>
> around foo => sub { my ($orig, $self, @args) = @_; $self->$orig(@args) * 2
> };
>
> package Class;
> use Moose;
>
> sub { with 'Double'; };
>
> has foo => (
>    is => 'ro'
> );
>
> package main;
>
> use Test::More;
>
> my $four = Class->new(foo => 2);
> is $four->foo, 4, 'So far so good';
> my $six = Class->new(foo =>  3);
> is $six->foo, 6, 'Not so good - returns 12';
> is $four->foo, 4, 'Really not so good, now returns 8!';
>
> done_testing;
>
> The last case being the key one - just by constructing a 2nd instance,
> you've had effects on what should be a totally un-related first instance -
> epic fail!
>
> Cheers
> t0m
>
>


-- 
woosley.xu.    http://twitter.com/redicaps
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.