stevan / p5-mop-redux

A(nother) MOP for Perl 5
139 stars 36 forks source link

custom attribute handling via new #15

Closed forwardever closed 10 years ago

forwardever commented 11 years ago
has $one;
has $two;
has $three;

TestClass->new(1, 2, 3);

submethod BUILDARGS (@params) {
   $one   => $params[0],
   $two   => $params[1],
   $three => $params[2]
}
stevan commented 11 years ago

Hmm, I will have to think about this one, I would sooner do something closer to Moose, like:

has $one;
has $two;
has $three;

submethod BUILDARGS ($_one, $_two, $_three) {
    return +{ one => $_one, two => $_two, three => $_three } 
}

Though that might get tricky since it is technically a class method.

forwardever commented 11 years ago

okay, would be great to have something more customizable, thanks

forwardever commented 11 years ago

have adjusted my first example, hope it makes more sense now

stevan commented 11 years ago

I need to finish up the traits stuff today, but I will keep thinking on this, but yeah, your example looks good.

stevan commented 11 years ago

@forwardever – I did some testing today and this works in the latest p5-mop

class Baz {
    has $bar;

    method new ($x) {
        $self->next::method( bar => $x )
    }

    method bar { $bar }
}

{
    my $baz = Baz->new( 10 );
    isa_ok($baz, 'Baz');
    is($baz->bar, 10, '... overriding new works');
}

It is not as nice as the BUILDARGS idea, but for now it does what you would want.

forwardever commented 11 years ago

nice workaround, long term, would be nice to get something like this:

use mop;

class TestClass {

    has $one;
    has $two;
    has $three;
    has $hello;

    method new (@params) {
       $one   = shift @params;
       $two   = shift @params;
       $three = shift @params;

       $self->next::method(@params);
    }

    method one {$one}
    method two {$two}
    method three {$three}
    method hello {$hello}

}

my $test = TestClass->new(1, 2, 3, hello => 'world');

warn $test->one;
warn $test->two;
warn $test->three;
warn $test->hello;
forwardever commented 11 years ago

which might not make sense, as $self is created in $self->next::method(@params)

stevan commented 11 years ago

yeah, this is a little tricky, but we are getting there

forwardever commented 11 years ago

basically, I like Rubys initialize method: http://ruby.activeventure.com/usersguide/rg/objinitialization.html

stevan commented 11 years ago

Yeah, I am taking a similar approach for inheriting from non-mop classes, ... https://github.com/stevan/p5-mop-redux/blob/master/t/050-non-mop-integration/003-attributes-in-non-mop-inherited-class.t so I think something like this could be worked out.

doy commented 11 years ago

For what it's worth, that's basically how BUILD works in perl 6.

stevan commented 10 years ago

I think this issue is basically resolved (especially since @forwardever has finally come around to our way of thinking re: attribute visibility in subclasses).