perl.moose http://www.nntp.perl.org/group/perl.moose/ Re: checking consistency between attributes by benh

From: benh I'm very anxious to see what come of this as I agree that this would
be very cool but I fail to see how it would help with the initial
question as triggers to not get fired until after construction?






On 7/16/08, Stevan Little <stevan.little@iinteractive.com> wrote:
>
> On Jul 16, 2008, at 4:39 PM, Charles Alderman wrote:
>
> > Speaking of triggers, why can't the trigger of an attribute be changed in
> an extended attribute? Like so:
> >
> > has '+foo' => ( trigger => sub {} );
> >
> > The docs only say the "feature is restricted somewhat, so as to try and
> force at least some sanity into it. You are only allowed to change the
> following attributes: [a list not including trigger]."
> >
> > Would it be as easy as adding "trigger" to
> Moose::Meta::Attribute::legal_options_for_inheritance()?
> (I tried that, and it worked initially. Am I missing some un-intended
> side-effects somewhere?)
> >
>
> No, that is all that needs to be done. The initial reasoning for those
> restrictions was to try and enforce some sanity into things rather then let
> them be changed randomly, blah blah, something about Liskov, etc. I mean
> there is something to be said for protecting users against their own
> stupidity here.
>
> But as time goes by there seems like the only sane restriction is really
> the "isa/does must be a subtype" thing, and probably weak_ref and auto_deref
> since they can break things in subtle ways if not used properly by the super
> class you are overriding from.
>
> So I guess I am saying yes, we can add trigger to the list of legal
> options.
>
>
> >
> > I guess there would be some screwiness (undecided behavior) in Sartak's
> plan for the method-modifier-like triggers? Thusly:
> >
> > package Foo;
> > use Moose;
> >
> > has 'foo' => (
> > is => 'rw',
> > trigger => { before => sub{} }
> > );
> >
> > package Foo::Bar;
> > use Moose;
> > extends 'Foo';
> >
> > +has 'foo' => ( trigger => { after => sub{} } );
> >
> > Would foo trigger before AND after now?
> >
>
> No, the override is not cumulative, it simply overrides it completely, so
> the foo trigger would only have an "after" for it.
>
> This is maybe the only place where this would be bad, so perhaps we should
> wait till Sartak finishes and see what we get before we add it to the legal
> options.
>
> - Stevan
>
>
>
>
> > Thanks,
> > Charles Alderman
> >
> >
> > ----- Original Message -----
> > From: Stevan Little <stevan.little@iinteractive.com>
> > Sent: Tue, 15 Jul 2008 23:05:32 -0400
> > Re: Re: checking consistency between attributes
> >
> >
> >
> >
> > > Ohh, I like this, very clean and re-using existing documentation :P
> > >
> > > It keeps it away from the type system too, which while it feels kinda
> > > sexy to integrate it with, it also feels wrong (not the good wrong, but
> > > the bad wrong).
> > >
> > > Sartak++ very very *very* well volunteered :)
> > >
> > > - Stevan
> > >
> > > On Jul 15, 2008, at 9:05 PM, Chris Prather wrote:
> > >
> > >
> > > > On Tue, 15 Jul 2008 20:55:44 -0400, Sartak wrote:
> > > >
> > > > > On Tue, Jul 15, 2008 at 8:29 PM, Stevan Little
> > > > > <stevan.little@iinteractive.com> wrote:
> > > > >
> > > > > > trigger => {
> > > > > > before => sub { ... },
> > > > > > after => sub { ... },
> > > > > > }
> > > > > >
> > > > >
> > > > > +1 awesome
> > > > >
> > > > >
> > > > > > The idea would be that the "after" would do the same as the
> normal trigger,
> > > > > > and the "before" would get the same arguments as the normal
> trigger except
> > > > > > the assignment would not have happened yet. The tricky bits are:
> > > > > >
> > > > >
> > > > > We already have something vaguely like this: method modifiers!
> > > > > Modeling multi-phase triggers after method modifiers would decrease
> > > > > cognitive load.
> > > > >
> > > > >
> > > > > > - do we make the "before" trigger return a value for us to assign?
> > > > > >
> > > > >
> > > > > No. The return value is discarded.
> > > > >
> > > > >
> > > > > > - do we make the "before" trigger actually do the assignment?
> > > > > >
> > > > >
> > > > > No. The before trigger is only there to perform additional
> validation
> > > > > or to call extra methods.
> > > > >
> > > > > We could have an "around" trigger which *does* wrap the assignment.
> > > > >
> > > > >
> > > > > > - what happens if an exception is thrown inside the "before", do
> we catch
> > > > > > it?
> > > > > >
> > > > >
> > > > > No. Exceptions are generally outside of the scope of Moose. We only
> > > > > throw them. :)
> > > > >
> > > > > Besides, before could be used mostly for exceptions, to do
> multi-value
> > > > > validation.
> > > > >
> > > > >
> > > > > > - how would you/should you be able to -- indicate failure or some
> kind in
> > > > > > before?
> > > > > >
> > > > >
> > > > > Throw an error. This is what we do and expect practically everywhere
> > > > > else, right?
> > > > >
> > > >
> > > > I second continuing the method modifier theme into triggers here.
> > > > Sartak hits the nail on the head, before/after/around are nicely
> > > > extended into this realm too. Keeping the theme means less confusion
> > > > when it comes time to document/explain this to people who are ...
> shall
> > > > we be kind and say intermediate moose users ... cause this is getting
> > > > well into the advanced realm.
> > > >
> > > > Well volunteered Sartak!
> > > >
> > > > -Chris
> > > >
> > >
> >
> >
> >
> >
>
>


--
benh~

2008-07-16T14:04:59Z
Re: checking consistency between attributes by Stevan Little

From: Stevan Little
On Jul 16, 2008, at 4:39 PM, Charles Alderman wrote:
> Speaking of triggers, why can't the trigger of an attribute be
> changed in an extended attribute? Like so:
>
> has '+foo' => ( trigger => sub {} );
>
> The docs only say the "feature is restricted somewhat, so as to try
> and force at least some sanity into it. You are only allowed to
> change the following attributes: [a list not including trigger]."
>
> Would it be as easy as adding "trigger" to
> Moose::Meta::Attribute::legal_options_for_inheritance()? (I tried
> that, and it worked initially. Am I missing some un-intended side-
> effects somewhere?)

No, that is all that needs to be done. The initial reasoning for
those restrictions was to try and enforce some sanity into things
rather then let them be changed randomly, blah blah, something about
Liskov, etc. I mean there is something to be said for protecting
users against their own stupidity here.

But as time goes by there seems like the only sane restriction is
really the "isa/does must be a subtype" thing, and probably weak_ref
and auto_deref since they can break things in subtle ways if not used
properly by the super class you are overriding from.

So I guess I am saying yes, we can add trigger to the list of legal
options.

>
> I guess there would be some screwiness (undecided behavior) in
> Sartak's plan for the method-modifier-like triggers? Thusly:
>
> package Foo;
> use Moose;
>
> has 'foo' => (
> is => 'rw',
> trigger => { before => sub{} }
> );
>
> package Foo::Bar;
> use Moose;
> extends 'Foo';
>
> +has 'foo' => ( trigger => { after => sub{} } );
>
> Would foo trigger before AND after now?

No, the override is not cumulative, it simply overrides it
completely, so the foo trigger would only have an "after" for it.

This is maybe the only place where this would be bad, so perhaps we
should wait till Sartak finishes and see what we get before we add it
to the legal options.

- Stevan


> Thanks,
> Charles Alderman
>
>
> ----- Original Message -----
> From: Stevan Little <stevan.little@iinteractive.com>
> Sent: Tue, 15 Jul 2008 23:05:32 -0400
> Re: Re: checking consistency between attributes
>
>
>
>> Ohh, I like this, very clean and re-using existing documentation :P
>>
>> It keeps it away from the type system too, which while it feels kinda
>> sexy to integrate it with, it also feels wrong (not the good
>> wrong, but
>> the bad wrong).
>>
>> Sartak++ very very *very* well volunteered :)
>>
>> - Stevan
>>
>> On Jul 15, 2008, at 9:05 PM, Chris Prather wrote:
>>
>>> On Tue, 15 Jul 2008 20:55:44 -0400, Sartak wrote:
>>>> On Tue, Jul 15, 2008 at 8:29 PM, Stevan Little
>>>> <stevan.little@iinteractive.com> wrote:
>>>>> trigger => {
>>>>> before => sub { ... },
>>>>> after => sub { ... },
>>>>> }
>>>>
>>>> +1 awesome
>>>>
>>>>> The idea would be that the "after" would do the same as the
>>>>> normal trigger,
>>>>> and the "before" would get the same arguments as the normal
>>>>> trigger except
>>>>> the assignment would not have happened yet. The tricky bits are:
>>>>
>>>> We already have something vaguely like this: method modifiers!
>>>> Modeling multi-phase triggers after method modifiers would decrease
>>>> cognitive load.
>>>>
>>>>> - do we make the "before" trigger return a value for us to assign?
>>>>
>>>> No. The return value is discarded.
>>>>
>>>>> - do we make the "before" trigger actually do the assignment?
>>>>
>>>> No. The before trigger is only there to perform additional
>>>> validation
>>>> or to call extra methods.
>>>>
>>>> We could have an "around" trigger which *does* wrap the assignment.
>>>>
>>>>> - what happens if an exception is thrown inside the "before",
>>>>> do we catch
>>>>> it?
>>>>
>>>> No. Exceptions are generally outside of the scope of Moose. We only
>>>> throw them. :)
>>>>
>>>> Besides, before could be used mostly for exceptions, to do multi-
>>>> value
>>>> validation.
>>>>
>>>>> - how would you/should you be able to -- indicate failure or
>>>>> some kind in
>>>>> before?
>>>>
>>>> Throw an error. This is what we do and expect practically
>>>> everywhere
>>>> else, right?
>>>
>>> I second continuing the method modifier theme into triggers here.
>>> Sartak hits the nail on the head, before/after/around are nicely
>>> extended into this realm too. Keeping the theme means less confusion
>>> when it comes time to document/explain this to people who are ...
>>> shall
>>> we be kind and say intermediate moose users ... cause this is
>>> getting
>>> well into the advanced realm.
>>>
>>> Well volunteered Sartak!
>>>
>>> -Chris
>
>
>

2008-07-16T13:51:50Z
Re: checking consistency between attributes by Charles Alderman

From: Charles Alderman Speaking of triggers, why can't the trigger of an attribute be changed
in an extended attribute? Like so:

has '+foo' => ( trigger => sub {} );

The docs only say the "feature is restricted somewhat, so as to try
and force at least some sanity into it. You are only allowed to change
the following attributes: [a list not including trigger]."

Would it be as easy as adding "trigger" to
Moose::Meta::Attribute::legal_options_for_inheritance()? (I tried
that, and it worked initially. Am I missing some un-intended
side-effects somewhere?)

I guess there would be some screwiness (undecided behavior) in
Sartak's plan for the method-modifier-like triggers? Thusly:

package Foo;
use Moose;

has 'foo' => (
is => 'rw',
trigger => { before => sub{} }
);

package Foo::Bar;
use Moose;
extends 'Foo';

+has 'foo' => ( trigger => { after => sub{} } );

Would foo trigger before AND after now?

Thanks,
Charles Alderman


----- Original Message -----
From: Stevan Little <stevan.little@iinteractive.com>
Sent: Tue, 15 Jul 2008 23:05:32 -0400
Re: Re: checking consistency between attributes



> Ohh, I like this, very clean and re-using existing documentation :P
>
> It keeps it away from the type system too, which while it feels kinda
> sexy to integrate it with, it also feels wrong (not the good wrong, but
> the bad wrong).
>
> Sartak++ very very *very* well volunteered :)
>
> - Stevan
>
> On Jul 15, 2008, at 9:05 PM, Chris Prather wrote:
>
>> On Tue, 15 Jul 2008 20:55:44 -0400, Sartak wrote:
>>> On Tue, Jul 15, 2008 at 8:29 PM, Stevan Little
>>> <stevan.little@iinteractive.com> wrote:
>>>> trigger => {
>>>> before => sub { ... },
>>>> after => sub { ... },
>>>> }
>>>
>>> +1 awesome
>>>
>>>> The idea would be that the "after" would do the same as the
>>>> normal trigger,
>>>> and the "before" would get the same arguments as the normal trigger except
>>>> the assignment would not have happened yet. The tricky bits are:
>>>
>>> We already have something vaguely like this: method modifiers!
>>> Modeling multi-phase triggers after method modifiers would decrease
>>> cognitive load.
>>>
>>>> - do we make the "before" trigger return a value for us to assign?
>>>
>>> No. The return value is discarded.
>>>
>>>> - do we make the "before" trigger actually do the assignment?
>>>
>>> No. The before trigger is only there to perform additional validation
>>> or to call extra methods.
>>>
>>> We could have an "around" trigger which *does* wrap the assignment.
>>>
>>>> - what happens if an exception is thrown inside the "before", do we catch
>>>> it?
>>>
>>> No. Exceptions are generally outside of the scope of Moose. We only
>>> throw them. :)
>>>
>>> Besides, before could be used mostly for exceptions, to do multi-value
>>> validation.
>>>
>>>> - how would you/should you be able to -- indicate failure or some kind in
>>>> before?
>>>
>>> Throw an error. This is what we do and expect practically everywhere
>>> else, right?
>>
>> I second continuing the method modifier theme into triggers here.
>> Sartak hits the nail on the head, before/after/around are nicely
>> extended into this realm too. Keeping the theme means less confusion
>> when it comes time to document/explain this to people who are ... shall
>> we be kind and say intermediate moose users ... cause this is getting
>> well into the advanced realm.
>>
>> Well volunteered Sartak!
>>
>> -Chris



2008-07-16T13:39:33Z
Re: Extending an attribute with a trait by Stevan Little

From: Stevan Little Dan,

Okay, couple of problems with the code:

> around 'legal_options_for_inheritance' => sub {
> my @options = inner();
> push @options, 'foo';
> return @options;
> };

This is not how to do an around, inner() is for augment, not for
around. This should be:

around 'legal_options_for_inheritance' => sub {
my $next = shift;
my $self = shift;
my @options = $self->$next();
push @options, 'foo';
return @options;
};

Then in your classes you had:

package MyClass;
use Moose;

has 'one' => (
is => 'rw',
isa => 'Str',
traits => [qw/Foo/],
foo => 'bar',
);

has 'two' => (
is => 'rw',
isa => 'Str',
);

package MySubClass;
use Moose;
extends 'MyClass';

has '+two' => (
traits => [qw/Foo/],
foo => 'baz',
);

You cannot modify "two" like that, your changing it too late for the
Foo trait to take effect. The application of the trait takes effect
after the options are parsed, not before.

package MySubClass;
use Moose;
extends 'MyClass';

has '+one' => (
foo => 'baz',
);

will work correctly though.

- Stevan





On Jul 16, 2008, at 12:39 PM, Dan Harbin wrote:

> I've attached it. You may have to twiddle the shabang line for your
> environment.
>
> Thanks for the help!
>
> On Wed, Jul 16, 2008 at 11:35 AM, Stevan Little
> <stevan.little@iinteractive.com> wrote:
>> Dan,
>>
>> Can you provide a complete and runnable example? It would make it
>> easier to
>> test/debug.
>>
>> Thanks,
>>
>> - Stevan
>>
>> On Jul 16, 2008, at 12:33 PM, Dan Harbin wrote:
>>
>>> This still doesn't seem to work. Maybe it only works by
>>> extending the
>>> attribute metaclass rather than applying a role like I'm trying.
>>>
>>> Here's the code. Help!
>>>
>>> -----------------------
>>>
>>> package Demo::Meta::Attribute::Trait::Foo;
>>> use Moose::Role;
>>>
>>> has foo => (
>>> is => 'rw',
>>> isa => 'Str',
>>> required => 1,
>>> );
>>>
>>> around 'legal_options_for_inheritance' => sub {
>>> my @options = inner();
>>> push @options, 'foo';
>>> return @options;
>>> };
>>>
>>> package Moose::Meta::Attribute::Custom::Trait::Foo;
>>> sub register_implementation { 'Demo::Meta::Attribute::Trait::Foo' }
>>>
>>>
>>> On Wed, Jul 16, 2008 at 10:35 AM, Stevan Little
>>> <stevan.little@iinteractive.com> wrote:
>>>>
>>>> Dan,
>>>>
>>>> Roles don't inherit, so you want 'around' instead of 'override'
>>>> sorry, my
>>>> fault i used a term that is also a keyword :)
>>>>
>>>> - Stevan
>>>>
>>>> On Jul 16, 2008, at 11:16 AM, Dan Harbin wrote:
>>>>
>>>>> Stevan,
>>>>>
>>>>> I changed the code as follows, and it still fails. This trait
>>>>> doesn't/can't inherit from Moose::Meta::Attribute, so I think the
>>>>> override method is a no-op. How do I fix this?
>>>>>
>>>>> Dan
>>>>>
>>>>> -----------------
>>>>>
>>>>> package Demo::Meta::Attribute::Trait::Foo;
>>>>> use Moose::Role;
>>>>>
>>>>> has foo => (
>>>>> is => 'rw',
>>>>> isa => 'Str',
>>>>> required => 1,
>>>>> );
>>>>>
>>>>> override 'legal_options_for_inheritance' => sub {
>>>>> my @options = super();
>>>>> push @options, 'foo';
>>>>> return @options;
>>>>> };
>>>>>
>>>>> package Moose::Meta::Attribute::Custom::Trait::Foo;
>>>>> sub register_implementation
>>>>> { 'Demo::Meta::Attribute::Trait::Foo' }
>>>>
>>>>
>>
>>
>> <test.pl>

2008-07-16T09:50:52Z
Re: Extending an attribute with a trait by Stevan Little

From: Stevan Little Dan,

Can you provide a complete and runnable example? It would make it
easier to test/debug.

Thanks,

- Stevan

On Jul 16, 2008, at 12:33 PM, Dan Harbin wrote:

> This still doesn't seem to work. Maybe it only works by extending the
> attribute metaclass rather than applying a role like I'm trying.
>
> Here's the code. Help!
>
> -----------------------
>
> package Demo::Meta::Attribute::Trait::Foo;
> use Moose::Role;
>
> has foo => (
> is => 'rw',
> isa => 'Str',
> required => 1,
> );
>
> around 'legal_options_for_inheritance' => sub {
> my @options = inner();
> push @options, 'foo';
> return @options;
> };
>
> package Moose::Meta::Attribute::Custom::Trait::Foo;
> sub register_implementation { 'Demo::Meta::Attribute::Trait::Foo' }
>
>
> On Wed, Jul 16, 2008 at 10:35 AM, Stevan Little
> <stevan.little@iinteractive.com> wrote:
>> Dan,
>>
>> Roles don't inherit, so you want 'around' instead of 'override'
>> sorry, my
>> fault i used a term that is also a keyword :)
>>
>> - Stevan
>>
>> On Jul 16, 2008, at 11:16 AM, Dan Harbin wrote:
>>
>>> Stevan,
>>>
>>> I changed the code as follows, and it still fails. This trait
>>> doesn't/can't inherit from Moose::Meta::Attribute, so I think the
>>> override method is a no-op. How do I fix this?
>>>
>>> Dan
>>>
>>> -----------------
>>>
>>> package Demo::Meta::Attribute::Trait::Foo;
>>> use Moose::Role;
>>>
>>> has foo => (
>>> is => 'rw',
>>> isa => 'Str',
>>> required => 1,
>>> );
>>>
>>> override 'legal_options_for_inheritance' => sub {
>>> my @options = super();
>>> push @options, 'foo';
>>> return @options;
>>> };
>>>
>>> package Moose::Meta::Attribute::Custom::Trait::Foo;
>>> sub register_implementation { 'Demo::Meta::Attribute::Trait::Foo' }
>>
>>

2008-07-16T09:37:50Z
Re: Extending an attribute with a trait by Dan Harbin

From: Dan Harbin This still doesn't seem to work. Maybe it only works by extending the
attribute metaclass rather than applying a role like I'm trying.

Here's the code. Help!

-----------------------

package Demo::Meta::Attribute::Trait::Foo;
use Moose::Role;

has foo => (
is => 'rw',
isa => 'Str',
required => 1,
);

around 'legal_options_for_inheritance' => sub {
my @options = inner();
push @options, 'foo';
return @options;
};

package Moose::Meta::Attribute::Custom::Trait::Foo;
sub register_implementation { 'Demo::Meta::Attribute::Trait::Foo' }


On Wed, Jul 16, 2008 at 10:35 AM, Stevan Little
<stevan.little@iinteractive.com> wrote:
> Dan,
>
> Roles don't inherit, so you want 'around' instead of 'override' sorry, my
> fault i used a term that is also a keyword :)
>
> - Stevan
>
> On Jul 16, 2008, at 11:16 AM, Dan Harbin wrote:
>
>> Stevan,
>>
>> I changed the code as follows, and it still fails. This trait
>> doesn't/can't inherit from Moose::Meta::Attribute, so I think the
>> override method is a no-op. How do I fix this?
>>
>> Dan
>>
>> -----------------
>>
>> package Demo::Meta::Attribute::Trait::Foo;
>> use Moose::Role;
>>
>> has foo => (
>> is => 'rw',
>> isa => 'Str',
>> required => 1,
>> );
>>
>> override 'legal_options_for_inheritance' => sub {
>> my @options = super();
>> push @options, 'foo';
>> return @options;
>> };
>>
>> package Moose::Meta::Attribute::Custom::Trait::Foo;
>> sub register_implementation { 'Demo::Meta::Attribute::Trait::Foo' }
>
>

2008-07-16T09:33:49Z
Re: Extending an attribute with a trait by Stevan Little

From: Stevan Little Dan,

Roles don't inherit, so you want 'around' instead of 'override'
sorry, my fault i used a term that is also a keyword :)

- Stevan

On Jul 16, 2008, at 11:16 AM, Dan Harbin wrote:

> Stevan,
>
> I changed the code as follows, and it still fails. This trait
> doesn't/can't inherit from Moose::Meta::Attribute, so I think the
> override method is a no-op. How do I fix this?
>
> Dan
>
> -----------------
>
> package Demo::Meta::Attribute::Trait::Foo;
> use Moose::Role;
>
> has foo => (
> is => 'rw',
> isa => 'Str',
> required => 1,
> );
>
> override 'legal_options_for_inheritance' => sub {
> my @options = super();
> push @options, 'foo';
> return @options;
> };
>
> package Moose::Meta::Attribute::Custom::Trait::Foo;
> sub register_implementation { 'Demo::Meta::Attribute::Trait::Foo' }

2008-07-16T08:37:50Z
Re: Extending an attribute with a trait by Dan Harbin

From: Dan Harbin Stevan,

I changed the code as follows, and it still fails. This trait
doesn't/can't inherit from Moose::Meta::Attribute, so I think the
override method is a no-op. How do I fix this?

Dan

-----------------

package Demo::Meta::Attribute::Trait::Foo;
use Moose::Role;

has foo => (
is => 'rw',
isa => 'Str',
required => 1,
);

override 'legal_options_for_inheritance' => sub {
my @options = super();
push @options, 'foo';
return @options;
};

package Moose::Meta::Attribute::Custom::Trait::Foo;
sub register_implementation { 'Demo::Meta::Attribute::Trait::Foo' }

2008-07-16T08:16:59Z
Re: Access the attribute metaclass from a typecoercion? by Stevan Little

From: Stevan Little Dan,

No sorry, however see the "checking consistency between attributes"
thread, Sartak will be working on a before/after/around version of
trigger which should be able to do exactly that.

- Stevan

On Jul 16, 2008, at 9:45 AM, Dan Harbin wrote:

> Stevan, Mooseniks,
>
> I have a "DateTime" attribute trait that has a "date_format" like so:
>
> has date_format => (
> is => 'rw',
> isa => 'Str',
> default => '%F %T',
> );
>
>
> I would like to have a type coercion that will use
> DateTime::Format::Strptime to coerce a Str into a DateTime based on
> that "date_format".
>
> For that, I would need access to the attribute metaclass from the
> "via" block. Is there a way?
>
> Dan

2008-07-16T07:23:27Z
Access the attribute metaclass from a typecoercion? by Dan Harbin

From: Dan Harbin Stevan, Mooseniks,

I have a "DateTime" attribute trait that has a "date_format" like so:

has date_format => (
is => 'rw',
isa => 'Str',
default => '%F %T',
);


I would like to have a type coercion that will use
DateTime::Format::Strptime to coerce a Str into a DateTime based on
that "date_format".

For that, I would need access to the attribute metaclass from the
"via" block. Is there a way?

Dan

2008-07-16T06:45:30Z
Re: checking consistency between attributes by Stevan Little

From: Stevan Little Ohh, I like this, very clean and re-using existing documentation :P

It keeps it away from the type system too, which while it feels kinda
sexy to integrate it with, it also feels wrong (not the good wrong,
but the bad wrong).

Sartak++ very very *very* well volunteered :)

- Stevan

On Jul 15, 2008, at 9:05 PM, Chris Prather wrote:

> On Tue, 15 Jul 2008 20:55:44 -0400, Sartak wrote:
>> On Tue, Jul 15, 2008 at 8:29 PM, Stevan Little
>> <stevan.little@iinteractive.com> wrote:
>>> trigger => {
>>> before => sub { ... },
>>> after => sub { ... },
>>> }
>>
>> +1 awesome
>>
>>> The idea would be that the "after" would do the same as the
>>> normal trigger,
>>> and the "before" would get the same arguments as the normal
>>> trigger except
>>> the assignment would not have happened yet. The tricky bits are:
>>
>> We already have something vaguely like this: method modifiers!
>> Modeling multi-phase triggers after method modifiers would decrease
>> cognitive load.
>>
>>> - do we make the "before" trigger return a value for us to assign?
>>
>> No. The return value is discarded.
>>
>>> - do we make the "before" trigger actually do the assignment?
>>
>> No. The before trigger is only there to perform additional validation
>> or to call extra methods.
>>
>> We could have an "around" trigger which *does* wrap the assignment.
>>
>>> - what happens if an exception is thrown inside the "before", do
>>> we catch
>>> it?
>>
>> No. Exceptions are generally outside of the scope of Moose. We only
>> throw them. :)
>>
>> Besides, before could be used mostly for exceptions, to do multi-
>> value
>> validation.
>>
>>> - how would you/should you be able to -- indicate failure or some
>>> kind in
>>> before?
>>
>> Throw an error. This is what we do and expect practically everywhere
>> else, right?
>
> I second continuing the method modifier theme into triggers here.
> Sartak hits the nail on the head, before/after/around are nicely
> extended into this realm too. Keeping the theme means less confusion
> when it comes time to document/explain this to people who are ...
> shall
> we be kind and say intermediate moose users ... cause this is getting
> well into the advanced realm.
>
> Well volunteered Sartak!
>
> -Chris

2008-07-15T20:07:55Z
Re: checking consistency between attributes by Christopher Brown

From: Christopher Brown Stevan et al.,

I see you have already put a considerable amount of thought into this.

- do we make the "before" trigger return a value for us to assign?
- do we make the "before" trigger actually do the assignment?

This is a tough one.

On the one hand, having the "before" trigger return the value to be assigned
seems most straight-forward. But from a usability stand point, you should
want to keep the "before" and "after" triggers as similar as possible. And
you don't want to restrict triggers in such a way. You want them to be able
to affect other attributes

has 'max' => (
...
trigger => {
before => sub {
$_[0]->max if $_[0]->min > $_[0]->max;
}
);

So yeah, I would have the "before" trigger responsible for setting the
assignment. I realize this is very tricky.


- what happens if an exception is thrown inside the "before", do we catch
it?
- how would you/should you be able to -- indicate failure or some kind in
before?

You would have to support some type of exception / failure handling, don't
you. Perhaps this could be caught and indicated in meta and the particular
exception retrievable with a sub call. Maybe you could support for a
DBI-type raise error mechanism that indicates if exceptions are caught and
how they are handled a la FATAL / WARN / IGNORE.

In any event, I will give it some more thought.

Best,

Chris

On Tue, Jul 15, 2008 at 5:29 PM, Stevan Little <
stevan.little@iinteractive.com> wrote:

> Chris,
>
> Yes, the key is to figure out the best place to add this feature. Trigger
> fires after the assignment has been made, which in this case is too late. We
> had talked about a multi-phase trigger which would allow a "before" and
> "after" options, like so:
>
> has foo => (
> is => 'rw',
> ...
> trigger => {
> before => sub { ... },
> after => sub { ... },
> }
> );
>
> this would allow the backward compat to be handled when trigger is a CODE
> ref, but the new feature could be handled when it is a HASH ref. This is not
> all that different then the inflate/deflate that DBIx::Class offers.
>
> The idea would be that the "after" would do the same as the normal trigger,
> and the "before" would get the same arguments as the normal trigger except
> the assignment would not have happened yet. The tricky bits are:
>
> - do we make the "before" trigger return a value for us to assign?
> - do we make the "before" trigger actually do the assignment?
> - what happens if an exception is thrown inside the "before", do we catch
> it?
> - how would you/should you be able to -- indicate failure or some kind in
> before?
>
> THoughts?
>
> - Stevan
>
>
>
>
> On Jul 15, 2008, at 4:55 PM, Christopher Brown wrote:
>
> Stevan, Benh, Charlie and Moose,
>>
>> My two cents is that ALL Moose users will eventually run into this as It
>> is not too uncommon. Think of all the applications that you use where one
>> of the parameters is interdependent upon another. Personally, I have used
>> both triggers and BUILD, but felt that be a better way. Using BUILD seems
>> like a more general solution, but BUILD separates the
>> check/coercion/constraint logic from the attribute definition. IMHO, a bad
>> thing. My thoughts this been that I have wanted a constraint argument to
>> the 'has' function that would fire the defined subroutine just before the
>> BUILD subroutine. Not sure how that would work or even if that is possible
>> in the given architecture.
>>
>> Best,
>>
>> Chris
>>
>>
>> What I have wanted is a constraint => argument to has that fires Perhaps
>> there should be a constraint => argument
>>
>> On Tue, Jul 15, 2008 at 9:15 AM, Stevan Little <
>> stevan.little@iinteractive.com> wrote:
>> Well the idea of a type check/coercion that has access to $self has been
>> on my mind for a while, but I have not figured out yet. Traditionally in
>> most type systems, especially those which are done at compile-time, you
>> don't have access to other runtime variables. There is a current research
>> path on something called "Dependent Types" which brings in the notion of
>> values, however this is some pretty complex stuff and some of it's
>> detractors have mused that to really type a program fully you would need to
>> execute it at compile-time, which means you would likely prove it can stop,
>> which gets into the whole "would a language with dependent types be turing
>> complete then?" question (which is also where it goes waaaaaaaay over my
>> head too).
>>
>> That said, I think we need a better facility then triggers.
>>
>> My concern is that putting this into the type system makes it into "action
>> at a distance" especially when it comes to coercions. It also ties a type
>> specifically to a class and so removes reusability (good thing, bad thing,
>> hard to say here).
>>
>> Anyway, it is in the back of my head, I have not forgotten about it. Part
>> of me fears it will require a type system overhaul/re-write though, so it
>> may not be coming soon.
>>
>> - Stevan
>>
>>
>>
>>
>> On Jul 15, 2008, at 4:13 AM, benh wrote:
>>
>> It seems that at the heart of it it seems that theres a missing event
>> that has access to self? My inital though was to just create a type
>> that was min, but types loose there context. I've been trying to wrap
>> my head around the code for this to see if there was some way to try
>> and have some other specified global structure that would still be in
>> scope, but I alway get lost in the passing of things when I look at
>> the type code.
>>
>> I was able to trick things out but it requires that most of the 'built
>> in' code structure gets re-done in BUILD, thus you have access to self
>> and you end up forcing a system where everything passes thru a
>> trigger. This allows you to check for any thing, but it does seem like
>> much more of a hack then the inital example...
>>
>> It's a bit tedious so I posted it elsewhere:
>>
>> http://develonizer.com/svn/misc/min_max.pl
>>
>>
>>
>>
>>
>> On 7/14/08, charlie@aldermania.com <charlie@aldermania.com> wrote:
>> How about this:
>>
>> has 'min' => (
>> is => 'rw',
>> isa => 'Int',
>> default => sub { NEGATIVE_INFINITY },
>> trigger => sub {
>> my ( $self, $val ) = @_;
>> carp "min is > max" unless $val <= $self->max;
>> }
>> );
>>
>> has 'max' => (
>> is => 'rw',
>> isa => 'Int',
>> default => sub { POSITIVE_INFINITY },
>> trigger => sub {
>> my ( $self, $val ) = @_;
>> carp "max is < min" unless $val >= $self->min;
>> }
>> );
>>
>> No BUILD needed. Consistency checked by the triggers whenever min and
>> max
>> are set...
>>
>> Besides defining negative and positive infinity, the only problem I see
>> is
>> if both min and max are set at the same time, as in the constructor. I
>> don't know which error you'd get if the object was initialized like this:
>>
>> my $foo = Foo->new(
>> min => 1,
>> max => -1,
>> );
>>
>> Charles Alderman
>>
>> ----- Original Message -----
>> From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
>> Sent: Mon, 14 Jul 2008 23:15:49 +0200
>> Re: checking consistency between attributes
>>
>>
>>
>>
>> Hello list.
>>
>> What's the best way to check consistency between attributes values ? Is
>> there anything better than a dedicated BUILD method, such as:
>>
>> use Moose;
>> use Carp;
>>
>> has 'min' => (is => 'rw', isa => 'Int');
>> has 'max' => (is => 'rw', isa => 'Int');
>>
>> sub BUILD {
>> my ($self, $params) = @_;
>>
>> my ($max, $min) = ($self->max(), $self->min());
>> croak "max < min" if defined $max && defined $min && $max < $min;
>> }
>> --
>> Guillaume Rousse
>> Moyens Informatiques - INRIA Futurs
>> Tel: 01 69 35 69 62
>>
>>
>>
>>
>>
>>
>>
>> --
>> benh~
>>
>>
>>
>

2008-07-15T18:46:01Z
Re: checking consistency between attributes by Chris Prather

From: Chris Prather On Tue, 15 Jul 2008 20:55:44 -0400, Sartak wrote:
> On Tue, Jul 15, 2008 at 8:29 PM, Stevan Little
> <stevan.little@iinteractive.com> wrote:
>> trigger => {
>> before => sub { ... },
>> after => sub { ... },
>> }
>
> +1 awesome
>
>> The idea would be that the "after" would do the same as the normal trigger,
>> and the "before" would get the same arguments as the normal trigger except
>> the assignment would not have happened yet. The tricky bits are:
>
> We already have something vaguely like this: method modifiers!
> Modeling multi-phase triggers after method modifiers would decrease
> cognitive load.
>
>> - do we make the "before" trigger return a value for us to assign?
>
> No. The return value is discarded.
>
>> - do we make the "before" trigger actually do the assignment?
>
> No. The before trigger is only there to perform additional validation
> or to call extra methods.
>
> We could have an "around" trigger which *does* wrap the assignment.
>
>> - what happens if an exception is thrown inside the "before", do we catch
>> it?
>
> No. Exceptions are generally outside of the scope of Moose. We only
> throw them. :)
>
> Besides, before could be used mostly for exceptions, to do multi-value
> validation.
>
>> - how would you/should you be able to -- indicate failure or some kind in
>> before?
>
> Throw an error. This is what we do and expect practically everywhere
> else, right?

I second continuing the method modifier theme into triggers here.
Sartak hits the nail on the head, before/after/around are nicely
extended into this realm too. Keeping the theme means less confusion
when it comes time to document/explain this to people who are ... shall
we be kind and say intermediate moose users ... cause this is getting
well into the advanced realm.

Well volunteered Sartak!

-Chris

2008-07-15T18:05:48Z
Re: checking consistency between attributes by Sartak

From: Sartak On Tue, Jul 15, 2008 at 8:29 PM, Stevan Little
<stevan.little@iinteractive.com> wrote:
> trigger => {
> before => sub { ... },
> after => sub { ... },
> }

+1 awesome

> The idea would be that the "after" would do the same as the normal trigger,
> and the "before" would get the same arguments as the normal trigger except
> the assignment would not have happened yet. The tricky bits are:

We already have something vaguely like this: method modifiers!
Modeling multi-phase triggers after method modifiers would decrease
cognitive load.

> - do we make the "before" trigger return a value for us to assign?

No. The return value is discarded.

> - do we make the "before" trigger actually do the assignment?

No. The before trigger is only there to perform additional validation
or to call extra methods.

We could have an "around" trigger which *does* wrap the assignment.

> - what happens if an exception is thrown inside the "before", do we catch
> it?

No. Exceptions are generally outside of the scope of Moose. We only
throw them. :)

Besides, before could be used mostly for exceptions, to do multi-value
validation.

> - how would you/should you be able to -- indicate failure or some kind in
> before?

Throw an error. This is what we do and expect practically everywhere
else, right?

Shawn

2008-07-15T17:55:52Z
Re: checking consistency between attributes by Stevan Little

From: Stevan Little Chris,

Yes, the key is to figure out the best place to add this feature.
Trigger fires after the assignment has been made, which in this case
is too late. We had talked about a multi-phase trigger which would
allow a "before" and "after" options, like so:

has foo => (
is => 'rw',
...
trigger => {
before => sub { ... },
after => sub { ... },
}
);

this would allow the backward compat to be handled when trigger is a
CODE ref, but the new feature could be handled when it is a HASH ref.
This is not all that different then the inflate/deflate that
DBIx::Class offers.

The idea would be that the "after" would do the same as the normal
trigger, and the "before" would get the same arguments as the normal
trigger except the assignment would not have happened yet. The tricky
bits are:

- do we make the "before" trigger return a value for us to assign?
- do we make the "before" trigger actually do the assignment?
- what happens if an exception is thrown inside the "before", do we
catch it?
- how would you/should you be able to -- indicate failure or some
kind in before?

THoughts?

- Stevan



On Jul 15, 2008, at 4:55 PM, Christopher Brown wrote:

> Stevan, Benh, Charlie and Moose,
>
> My two cents is that ALL Moose users will eventually run into this
> as It is not too uncommon. Think of all the applications that you
> use where one of the parameters is interdependent upon another.
> Personally, I have used both triggers and BUILD, but felt that be a
> better way. Using BUILD seems like a more general solution, but
> BUILD separates the check/coercion/constraint logic from the
> attribute definition. IMHO, a bad thing. My thoughts this been
> that I have wanted a constraint argument to the 'has' function that
> would fire the defined subroutine just before the BUILD subroutine.
> Not sure how that would work or even if that is possible in the
> given architecture.
>
> Best,
>
> Chris
>
>
> What I have wanted is a constraint => argument to has that fires
> Perhaps there should be a constraint => argument
>
> On Tue, Jul 15, 2008 at 9:15 AM, Stevan Little
> <stevan.little@iinteractive.com> wrote:
> Well the idea of a type check/coercion that has access to $self has
> been on my mind for a while, but I have not figured out yet.
> Traditionally in most type systems, especially those which are done
> at compile-time, you don't have access to other runtime variables.
> There is a current research path on something called "Dependent
> Types" which brings in the notion of values, however this is some
> pretty complex stuff and some of it's detractors have mused that to
> really type a program fully you would need to execute it at compile-
> time, which means you would likely prove it can stop, which gets
> into the whole "would a language with dependent types be turing
> complete then?" question (which is also where it goes waaaaaaaay
> over my head too).
>
> That said, I think we need a better facility then triggers.
>
> My concern is that putting this into the type system makes it into
> "action at a distance" especially when it comes to coercions. It
> also ties a type specifically to a class and so removes reusability
> (good thing, bad thing, hard to say here).
>
> Anyway, it is in the back of my head, I have not forgotten about
> it. Part of me fears it will require a type system overhaul/re-
> write though, so it may not be coming soon.
>
> - Stevan
>
>
>
>
> On Jul 15, 2008, at 4:13 AM, benh wrote:
>
> It seems that at the heart of it it seems that theres a missing event
> that has access to self? My inital though was to just create a type
> that was min, but types loose there context. I've been trying to wrap
> my head around the code for this to see if there was some way to try
> and have some other specified global structure that would still be in
> scope, but I alway get lost in the passing of things when I look at
> the type code.
>
> I was able to trick things out but it requires that most of the 'built
> in' code structure gets re-done in BUILD, thus you have access to self
> and you end up forcing a system where everything passes thru a
> trigger. This allows you to check for any thing, but it does seem like
> much more of a hack then the inital example...
>
> It's a bit tedious so I posted it elsewhere:
>
> http://develonizer.com/svn/misc/min_max.pl
>
>
>
>
>
> On 7/14/08, charlie@aldermania.com <charlie@aldermania.com> wrote:
> How about this:
>
> has 'min' => (
> is => 'rw',
> isa => 'Int',
> default => sub { NEGATIVE_INFINITY },
> trigger => sub {
> my ( $self, $val ) = @_;
> carp "min is > max" unless $val <= $self->max;
> }
> );
>
> has 'max' => (
> is => 'rw',
> isa => 'Int',
> default => sub { POSITIVE_INFINITY },
> trigger => sub {
> my ( $self, $val ) = @_;
> carp "max is < min" unless $val >= $self->min;
> }
> );
>
> No BUILD needed. Consistency checked by the triggers whenever min
> and max
> are set...
>
> Besides defining negative and positive infinity, the only problem
> I see is
> if both min and max are set at the same time, as in the
> constructor. I
> don't know which error you'd get if the object was initialized like
> this:
>
> my $foo = Foo->new(
> min => 1,
> max => -1,
> );
>
> Charles Alderman
>
> ----- Original Message -----
> From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
> Sent: Mon, 14 Jul 2008 23:15:49 +0200
> Re: checking consistency between attributes
>
>
>
>
> Hello list.
>
> What's the best way to check consistency between attributes
> values ? Is
> there anything better than a dedicated BUILD method, such as:
>
> use Moose;
> use Carp;
>
> has 'min' => (is => 'rw', isa => 'Int');
> has 'max' => (is => 'rw', isa => 'Int');
>
> sub BUILD {
> my ($self, $params) = @_;
>
> my ($max, $min) = ($self->max(), $self->min());
> croak "max < min" if defined $max && defined $min && $max < $min;
> }
> --
> Guillaume Rousse
> Moyens Informatiques - INRIA Futurs
> Tel: 01 69 35 69 62
>
>
>
>
>
>
>
> --
> benh~
>
>

2008-07-15T17:31:45Z
Re: Extending an attribute with a trait by Stevan Little

From: Stevan Little Dan,

Yes, there is, if you override the method
"legal_options_for_inheritance" in Moose::Meta::Attribute in your
trait so that it includes "foo" as well and that should do it.

- Stevan

On Jul 15, 2008, at 4:55 PM, Dan Harbin wrote:

> Stevan, other Moose-people,
>
> I'm having a problem using an attribute trait in a subclass. If I
> have an attribute in the superclass, then extend that attribute in the
> subclass by adding a trait, it complains about the behavior I'm adding
> with: Illegal inherited options => (foo). Since I made "foo"
> required, then I can't add the trait without it complaining: Attribute
> (foo) is required.
>
> The following code demonstrates this issue. Is there a workaround?
>
> -----------------------
>
> package Demo::Meta::Attribute::Trait::Foo;
> use Moose::Role;
>
> has foo => (
> is => 'rw',
> isa => 'Str',
> required => 1,
> );
>
> package Moose::Meta::Attribute::Custom::Trait::Foo;
> sub register_implementation { 'Demo::Meta::Attribute::Trait::Foo' }
>
> package MyClass;
> use Moose;
>
> has 'one' => (
> is => 'rw',
> isa => 'Str',
> traits => [qw/Foo/],
> foo => 'bar',
> );
>
> has 'two' => (
> is => 'rw',
> isa => 'Str',
> );
>
> package MySubClass;
> use Moose;
> extends 'MyClass';
>
> has '+two' => (
> traits => [qw/Foo/],
> foo => 'baz',
> );
>
> package main;
> use strict;
> use warnings;
>
> my $o = MySubClass->new();
>
> 1;

2008-07-15T17:23:49Z
Re: checking consistency between attributes by Christopher Brown

From: Christopher Brown Stevan, Benh, Charlie and Moose,

My two cents is that ALL Moose users will eventually run into this as It is
not too uncommon. Think of all the applications that you use where one of
the parameters is interdependent upon another. Personally, I have used both
triggers and BUILD, but felt that be a better way. Using BUILD seems like a
more general solution, but BUILD separates the check/coercion/constraint
logic from the attribute definition. IMHO, a bad thing. My thoughts this
been that I have wanted a constraint argument to the 'has' function that
would fire the defined subroutine just before the BUILD subroutine. Not sure
how that would work or even if that is possible in the given architecture.

Best,

Chris


What I have wanted is a constraint => argument to has that fires Perhaps
there should be a constraint => argument

On Tue, Jul 15, 2008 at 9:15 AM, Stevan Little <
stevan.little@iinteractive.com> wrote:

> Well the idea of a type check/coercion that has access to $self has been on
> my mind for a while, but I have not figured out yet. Traditionally in most
> type systems, especially those which are done at compile-time, you don't
> have access to other runtime variables. There is a current research path on
> something called "Dependent Types" which brings in the notion of values,
> however this is some pretty complex stuff and some of it's detractors have
> mused that to really type a program fully you would need to execute it at
> compile-time, which means you would likely prove it can stop, which gets
> into the whole "would a language with dependent types be turing complete
> then?" question (which is also where it goes waaaaaaaay over my head too).
>
> That said, I think we need a better facility then triggers.
>
> My concern is that putting this into the type system makes it into "action
> at a distance" especially when it comes to coercions. It also ties a type
> specifically to a class and so removes reusability (good thing, bad thing,
> hard to say here).
>
> Anyway, it is in the back of my head, I have not forgotten about it. Part
> of me fears it will require a type system overhaul/re-write though, so it
> may not be coming soon.
>
> - Stevan
>
>
>
>
> On Jul 15, 2008, at 4:13 AM, benh wrote:
>
> It seems that at the heart of it it seems that theres a missing event
>> that has access to self? My inital though was to just create a type
>> that was min, but types loose there context. I've been trying to wrap
>> my head around the code for this to see if there was some way to try
>> and have some other specified global structure that would still be in
>> scope, but I alway get lost in the passing of things when I look at
>> the type code.
>>
>> I was able to trick things out but it requires that most of the 'built
>> in' code structure gets re-done in BUILD, thus you have access to self
>> and you end up forcing a system where everything passes thru a
>> trigger. This allows you to check for any thing, but it does seem like
>> much more of a hack then the inital example...
>>
>> It's a bit tedious so I posted it elsewhere:
>>
>> http://develonizer.com/svn/misc/min_max.pl
>>
>>
>>
>>
>>
>> On 7/14/08, charlie@aldermania.com <charlie@aldermania.com> wrote:
>>
>>> How about this:
>>>
>>> has 'min' => (
>>> is => 'rw',
>>> isa => 'Int',
>>> default => sub { NEGATIVE_INFINITY },
>>> trigger => sub {
>>> my ( $self, $val ) = @_;
>>> carp "min is > max" unless $val <= $self->max;
>>> }
>>> );
>>>
>>> has 'max' => (
>>> is => 'rw',
>>> isa => 'Int',
>>> default => sub { POSITIVE_INFINITY },
>>> trigger => sub {
>>> my ( $self, $val ) = @_;
>>> carp "max is < min" unless $val >= $self->min;
>>> }
>>> );
>>>
>>> No BUILD needed. Consistency checked by the triggers whenever min and
>>> max
>>> are set...
>>>
>>> Besides defining negative and positive infinity, the only problem I see
>>> is
>>> if both min and max are set at the same time, as in the constructor. I
>>> don't know which error you'd get if the object was initialized like this:
>>>
>>> my $foo = Foo->new(
>>> min => 1,
>>> max => -1,
>>> );
>>>
>>> Charles Alderman
>>>
>>> ----- Original Message -----
>>> From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
>>> Sent: Mon, 14 Jul 2008 23:15:49 +0200
>>> Re: checking consistency between attributes
>>>
>>>
>>>
>>>
>>> Hello list.
>>>>
>>>> What's the best way to check consistency between attributes values ? Is
>>>> there anything better than a dedicated BUILD method, such as:
>>>>
>>>> use Moose;
>>>> use Carp;
>>>>
>>>> has 'min' => (is => 'rw', isa => 'Int');
>>>> has 'max' => (is => 'rw', isa => 'Int');
>>>>
>>>> sub BUILD {
>>>> my ($self, $params) = @_;
>>>>
>>>> my ($max, $min) = ($self->max(), $self->min());
>>>> croak "max < min" if defined $max && defined $min && $max < $min;
>>>> }
>>>> --
>>>> Guillaume Rousse
>>>> Moyens Informatiques - INRIA Futurs
>>>> Tel: 01 69 35 69 62
>>>>
>>>>
>>>
>>>
>>>
>>>
>>
>> --
>> benh~
>>
>
>

2008-07-15T13:56:10Z
Extending an attribute with a trait by Dan Harbin

From: Dan Harbin Stevan, other Moose-people,

I'm having a problem using an attribute trait in a subclass. If I
have an attribute in the superclass, then extend that attribute in the
subclass by adding a trait, it complains about the behavior I'm adding
with: Illegal inherited options => (foo). Since I made "foo"
required, then I can't add the trait without it complaining: Attribute
(foo) is required.

The following code demonstrates this issue. Is there a workaround?

-----------------------

package Demo::Meta::Attribute::Trait::Foo;
use Moose::Role;

has foo => (
is => 'rw',
isa => 'Str',
required => 1,
);

package Moose::Meta::Attribute::Custom::Trait::Foo;
sub register_implementation { 'Demo::Meta::Attribute::Trait::Foo' }

package MyClass;
use Moose;

has 'one' => (
is => 'rw',
isa => 'Str',
traits => [qw/Foo/],
foo => 'bar',
);

has 'two' => (
is => 'rw',
isa => 'Str',
);

package MySubClass;
use Moose;
extends 'MyClass';

has '+two' => (
traits => [qw/Foo/],
foo => 'baz',
);

package main;
use strict;
use warnings;

my $o = MySubClass->new();

1;

2008-07-15T13:55:23Z
Re: checking consistency between attributes by Stevan Little

From: Stevan Little Well the idea of a type check/coercion that has access to $self has
been on my mind for a while, but I have not figured out yet.
Traditionally in most type systems, especially those which are done
at compile-time, you don't have access to other runtime variables.
There is a current research path on something called "Dependent
Types" which brings in the notion of values, however this is some
pretty complex stuff and some of it's detractors have mused that to
really type a program fully you would need to execute it at compile-
time, which means you would likely prove it can stop, which gets into
the whole "would a language with dependent types be turing complete
then?" question (which is also where it goes waaaaaaaay over my head
too).

That said, I think we need a better facility then triggers.

My concern is that putting this into the type system makes it into
"action at a distance" especially when it comes to coercions. It also
ties a type specifically to a class and so removes reusability (good
thing, bad thing, hard to say here).

Anyway, it is in the back of my head, I have not forgotten about it.
Part of me fears it will require a type system overhaul/re-write
though, so it may not be coming soon.

- Stevan



On Jul 15, 2008, at 4:13 AM, benh wrote:

> It seems that at the heart of it it seems that theres a missing event
> that has access to self? My inital though was to just create a type
> that was min, but types loose there context. I've been trying to wrap
> my head around the code for this to see if there was some way to try
> and have some other specified global structure that would still be in
> scope, but I alway get lost in the passing of things when I look at
> the type code.
>
> I was able to trick things out but it requires that most of the 'built
> in' code structure gets re-done in BUILD, thus you have access to self
> and you end up forcing a system where everything passes thru a
> trigger. This allows you to check for any thing, but it does seem like
> much more of a hack then the inital example...
>
> It's a bit tedious so I posted it elsewhere:
>
> http://develonizer.com/svn/misc/min_max.pl
>
>
>
>
>
> On 7/14/08, charlie@aldermania.com <charlie@aldermania.com> wrote:
>> How about this:
>>
>> has 'min' => (
>> is => 'rw',
>> isa => 'Int',
>> default => sub { NEGATIVE_INFINITY },
>> trigger => sub {
>> my ( $self, $val ) = @_;
>> carp "min is > max" unless $val <= $self->max;
>> }
>> );
>>
>> has 'max' => (
>> is => 'rw',
>> isa => 'Int',
>> default => sub { POSITIVE_INFINITY },
>> trigger => sub {
>> my ( $self, $val ) = @_;
>> carp "max is < min" unless $val >= $self->min;
>> }
>> );
>>
>> No BUILD needed. Consistency checked by the triggers whenever
>> min and max
>> are set...
>>
>> Besides defining negative and positive infinity, the only problem
>> I see is
>> if both min and max are set at the same time, as in the
>> constructor. I
>> don't know which error you'd get if the object was initialized
>> like this:
>>
>> my $foo = Foo->new(
>> min => 1,
>> max => -1,
>> );
>>
>> Charles Alderman
>>
>> ----- Original Message -----
>> From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
>> Sent: Mon, 14 Jul 2008 23:15:49 +0200
>> Re: checking consistency between attributes
>>
>>
>>
>>
>>> Hello list.
>>>
>>> What's the best way to check consistency between attributes
>>> values ? Is
>>> there anything better than a dedicated BUILD method, such as:
>>>
>>> use Moose;
>>> use Carp;
>>>
>>> has 'min' => (is => 'rw', isa => 'Int');
>>> has 'max' => (is => 'rw', isa => 'Int');
>>>
>>> sub BUILD {
>>> my ($self, $params) = @_;
>>>
>>> my ($max, $min) = ($self->max(), $self->min());
>>> croak "max < min" if defined $max && defined $min && $max < $min;
>>> }
>>> --
>>> Guillaume Rousse
>>> Moyens Informatiques - INRIA Futurs
>>> Tel: 01 69 35 69 62
>>>
>>
>>
>>
>>
>
>
> --
> benh~

2008-07-15T09:17:44Z
Re: checking consistency between attributes by benh

From: benh It seems that at the heart of it it seems that theres a missing event
that has access to self? My inital though was to just create a type
that was min, but types loose there context. I've been trying to wrap
my head around the code for this to see if there was some way to try
and have some other specified global structure that would still be in
scope, but I alway get lost in the passing of things when I look at
the type code.

I was able to trick things out but it requires that most of the 'built
in' code structure gets re-done in BUILD, thus you have access to self
and you end up forcing a system where everything passes thru a
trigger. This allows you to check for any thing, but it does seem like
much more of a hack then the inital example...

It's a bit tedious so I posted it elsewhere:

http://develonizer.com/svn/misc/min_max.pl





On 7/14/08, charlie@aldermania.com <charlie@aldermania.com> wrote:
> How about this:
>
> has 'min' => (
> is => 'rw',
> isa => 'Int',
> default => sub { NEGATIVE_INFINITY },
> trigger => sub {
> my ( $self, $val ) = @_;
> carp "min is > max" unless $val <= $self->max;
> }
> );
>
> has 'max' => (
> is => 'rw',
> isa => 'Int',
> default => sub { POSITIVE_INFINITY },
> trigger => sub {
> my ( $self, $val ) = @_;
> carp "max is < min" unless $val >= $self->min;
> }
> );
>
> No BUILD needed. Consistency checked by the triggers whenever min and max
> are set...
>
> Besides defining negative and positive infinity, the only problem I see is
> if both min and max are set at the same time, as in the constructor. I
> don't know which error you'd get if the object was initialized like this:
>
> my $foo = Foo->new(
> min => 1,
> max => -1,
> );
>
> Charles Alderman
>
> ----- Original Message -----
> From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
> Sent: Mon, 14 Jul 2008 23:15:49 +0200
> Re: checking consistency between attributes
>
>
>
>
> > Hello list.
> >
> > What's the best way to check consistency between attributes values ? Is
> > there anything better than a dedicated BUILD method, such as:
> >
> > use Moose;
> > use Carp;
> >
> > has 'min' => (is => 'rw', isa => 'Int');
> > has 'max' => (is => 'rw', isa => 'Int');
> >
> > sub BUILD {
> > my ($self, $params) = @_;
> >
> > my ($max, $min) = ($self->max(), $self->min());
> > croak "max < min" if defined $max && defined $min && $max < $min;
> > }
> > --
> > Guillaume Rousse
> > Moyens Informatiques - INRIA Futurs
> > Tel: 01 69 35 69 62
> >
>
>
>
>


--
benh~

2008-07-15T01:13:28Z
Re: checking consistency between attributes by charlie

From: charlie How about this:

has 'min' => (
is => 'rw',
isa => 'Int',
default => sub { NEGATIVE_INFINITY },
trigger => sub {
my ( $self, $val ) = @_;
carp "min is > max" unless $val <= $self->max;
}
);

has 'max' => (
is => 'rw',
isa => 'Int',
default => sub { POSITIVE_INFINITY },
trigger => sub {
my ( $self, $val ) = @_;
carp "max is < min" unless $val >= $self->min;
}
);

No BUILD needed. Consistency checked by the triggers whenever min and
max are set...

Besides defining negative and positive infinity, the only problem I
see is if both min and max are set at the same time, as in the
constructor. I don't know which error you'd get if the object was
initialized like this:

my $foo = Foo->new(
min => 1,
max => -1,
);

Charles Alderman

----- Original Message -----
From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
Sent: Mon, 14 Jul 2008 23:15:49 +0200
Re: checking consistency between attributes



> Hello list.
>
> What's the best way to check consistency between attributes values ? Is
> there anything better than a dedicated BUILD method, such as:
>
> use Moose;
> use Carp;
>
> has 'min' => (is => 'rw', isa => 'Int');
> has 'max' => (is => 'rw', isa => 'Int');
>
> sub BUILD {
> my ($self, $params) = @_;
>
> my ($max, $min) = ($self->max(), $self->min());
> croak "max < min" if defined $max && defined $min && $max < $min;
> }
> --
> Guillaume Rousse
> Moyens Informatiques - INRIA Futurs
> Tel: 01 69 35 69 62



2008-07-14T18:24:36Z
Re: checking consistency between attributes by Stevan Little

From: Stevan Little
On Jul 14, 2008, at 5:35 PM, Charles Alderman wrote:
> Besides defining negative and positive infinity, the only problem I
> see is if both min and max are set at the same time, as in the
> constructor. I don't know which error you'd get if the object was
> initialized like this:
>
> my $foo = Foo->new(
> min => 1,
> max => -1,
> );

Attributes are stored in a hash so there is no way to determine for
sure which one will be created first. However I suspect that it
wouldn't matter too much anyway.

- Stevan


> Charles Alderman
>
> ----- Original Message -----
> From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
> Sent: Mon, 14 Jul 2008 23:15:49 +0200
> Re: checking consistency between attributes
>
>
>
>> Hello list.
>>
>> What's the best way to check consistency between attributes
>> values ? Is
>> there anything better than a dedicated BUILD method, such as:
>>
>> use Moose;
>> use Carp;
>>
>> has 'min' => (is => 'rw', isa => 'Int');
>> has 'max' => (is => 'rw', isa => 'Int');
>>
>> sub BUILD {
>> my ($self, $params) = @_;
>>
>> my ($max, $min) = ($self->max(), $self->min());
>> croak "max < min" if defined $max && defined $min && $max < $min;
>> }
>> --
>> Guillaume Rousse
>> Moyens Informatiques - INRIA Futurs
>> Tel: 01 69 35 69 62
>
>
>

2008-07-14T14:46:59Z
Re: Defining a parameterized subtype by Stevan Little

From: Stevan Little Guillaume,

Take a look at how the Maybe[`a] type is implemented (on line 615 of
Moose::Util::TypeConstraints) and use that as a guide.

Currently there is no clean, or easy way to do this though, you are
stepping into new territory.

- Stevan

On Jul 14, 2008, at 5:16 PM, Guillaume Rousse wrote:
> Hello list.
>
> I'd like to define my own parameterized ClassName subtype, to
> enforce inheritance from a given class. Something more generic than
>
> subtype 'FooClassName'
> => as 'ClassName'
> => where { $_->isa('Foo') };
>
> subtype 'BarClassName'
> => as 'ClassName'
> => where { $_->isa('Bar') };
>
> etc...
>
> I found a 'add_parameterizable_type' method in
> Moose::Util::TypeConstraints, but not much details about to
> retrieve the parameter in the constraint clause.
> --
> Guillaume Rousse
> Moyens Informatiques - INRIA Futurs
> Tel: 01 69 35 69 62

2008-07-14T14:44:29Z
Re: checking consistency between attributes by Charles Alderman

From: Charles Alderman How about this:

has 'min' => (
is => 'rw',
isa => 'Int',
default => sub { NEGATIVE_INFINITY },
trigger => sub {
my ( $self, $val ) = @_;
carp "min is > max" unless $val <= $self->max;
}
);

has 'max' => (
is => 'rw',
isa => 'Int',
default => sub { POSITIVE_INFINITY },
trigger => sub {
my ( $self, $val ) = @_;
carp "max is < min" unless $val >= $self->min;
}
);

No BUILD needed. Consistency checked by the triggers whenever min and
max are set...

Besides defining negative and positive infinity, the only problem I
see is if both min and max are set at the same time, as in the
constructor. I don't know which error you'd get if the object was
initialized like this:

my $foo = Foo->new(
min => 1,
max => -1,
);

Charles Alderman

----- Original Message -----
From: Guillaume Rousse <Guillaume.Rousse@inria.fr>
Sent: Mon, 14 Jul 2008 23:15:49 +0200
Re: checking consistency between attributes



> Hello list.
>
> What's the best way to check consistency between attributes values ? Is
> there anything better than a dedicated BUILD method, such as:
>
> use Moose;
> use Carp;
>
> has 'min' => (is => 'rw', isa => 'Int');
> has 'max' => (is => 'rw', isa => 'Int');
>
> sub BUILD {
> my ($self, $params) = @_;
>
> my ($max, $min) = ($self->max(), $self->min());
> croak "max < min" if defined $max && defined $min && $max < $min;
> }
> --
> Guillaume Rousse
> Moyens Informatiques - INRIA Futurs
> Tel: 01 69 35 69 62



2008-07-14T14:36:02Z
Defining a parameterized subtype by Guillaume Rousse

From: Guillaume Rousse Hello list.

I'd like to define my own parameterized ClassName subtype, to enforce
inheritance from a given class. Something more generic than

subtype 'FooClassName'
=> as 'ClassName'
=> where { $_->isa('Foo') };

subtype 'BarClassName'
=> as 'ClassName'
=> where { $_->isa('Bar') };

etc...

I found a 'add_parameterizable_type' method in
Moose::Util::TypeConstraints, but not much details about to retrieve the
parameter in the constraint clause.
--
Guillaume Rousse
Moyens Informatiques - INRIA Futurs
Tel: 01 69 35 69 62

2008-07-14T14:16:20Z
checking consistency between attributes by Guillaume Rousse

From: Guillaume Rousse Hello list.

What's the best way to check consistency between attributes values ? Is
there anything better than a dedicated BUILD method, such as:

use Moose;
use Carp;

has 'min' => (is => 'rw', isa => 'Int');
has 'max' => (is => 'rw', isa => 'Int');

sub BUILD {
my ($self, $params) = @_;

my ($max, $min) = ($self->max(), $self->min());
croak "max < min" if defined $max && defined $min && $max < $min;
}
--
Guillaume Rousse
Moyens Informatiques - INRIA Futurs
Tel: 01 69 35 69 62

2008-07-14T14:16:00Z
Re: Extends type questions by Stevan Little

From: Stevan Little Yeah this is a common problem when you need to extend a set of
interdependent classes, the only good solution that I have found for
it is to use some kind of Inversion of Control pattern/framework.
However a full IOC framework like IOC.pm or Bread::Board tend to be a
heavyweight solution and most often not appropriate for small stuff.

Since this is CPAN module and you don't control the internals, one
possible solution might be to use an 'after' method modifier to
"upgrade" your Module::B instance to MooseX::Module::B. It is
hackish, but it will get the job done and (hopefully) keep the hack
isolated.

And remember that you can pass in more than one method name to
'after' as well so you can do:

after 'create_b', 'build_me_some_b', 'gotta_have_that_b' => sub {
my $self = shift;
$self->{b} = $self->upgrade_b_to_mxb($self->{b});
};

sub upgrade_b_to_mxb {
my ($self, $old_b) = @_;
return MooseX::Module::B->new(__instance__ => $old_b);
}

And you can put this 'after' modifier and the upgrader in a Role that
can be re-applied to many classes if need be. The goal here being
that you only have to write your ugly hack in one place. Hehe, ...
Moose helps you write better bad code too :)

The other (better) solution is to fix the upstream module so that it
uses methods to create the related objects and then you can easily
override those objects.

- Stevan

On Jul 2, 2008, at 11:28 PM, benh wrote:

> I'm with Chris, this is more of a design issue. What is the common
> part between A and B that could not be pulled out to a role?
>
> On 7/2/08, Chris Prather <chris@prather.org> wrote:
>> On Wed, 2 Jul 2008 17:22:44 -0700, Christopher Brown wrote:
>>> Hi All,
>>>
>>> What is the best way to moosify an existing CPAN class and all
>>> the classes
>>> called by this class. I know that *extends* works:
>>>
>>> package MooseX::Module::A;
>>> use Moose;
>>> extends 'Module::A';
>>>
>>>
>>> package MooseX::Module::B;
>>> use Moose;
>>> extends 'Module::B';
>>>
>>> sub my_b_extension {
>>> ...
>>> }
>>>
>>>
>>> But how do you extend both modules when Module::A relies on and
>>> calls
>>> Module::B? Such as.
>>>
>>> package Module::A;.
>>>
>>> sub create_b {
>>> my $self = shift;
>>> $self->{b} = Module::B->new();
>>> }
>>>
>>> ...
>>>
>>> Now in:
>>>
>>> package main;
>>> use MooseX::Module::A;
>>> use MooseX::Module::B;
>>>
>>> my $a = Moose::X::Module::A->new(); # Cool
>>> $a->create_b; # Cool
>>> $a->{b}->my_b_extension(); # FAIL!
>>>
>>> In this scenario, I will not see *my_b_extension*. In normal,
>>> non-Moose
>>> Perl, I would:
>>>
>>> package Module::AX;
>>> use *base* 'Module::A';
>>> ...
>>>
>>> package Module::BX;
>>> use *base* 'Module::B';
>>> ...
>>>
>>
>>
>> Well base.pm and moose play fairly nice together ... but I'm not sure
>> even base.pm would solve this ...
>>
>> $self->{b} = Module::B->new(); # you hardcode the module name
>> here ...
>> nothing can save you now
>>
>> you'd need to override the create_b method in MX::Module::A ...
>> which
>> you'd have to do in any perl code because you've hardcoded the
>> classname in the method. This isn't a Moose problem, this is a
>> crappy
>> design decision problem.
>>
>> If you want to be able to subclass Module::B ... then create_b
>> either
>> needs to make the classname for B configurable (via a parameter
>> to the
>> method, or an attribute in A or something...) or you need to
>> override
>> it in your subclass of A to call the class you need ... (or you
>> override it with something configurable).
>>
>>
>> -Chris
>>
>
>
> --
> benh~

2008-07-02T20:49:09Z
Re: Extends type questions by benh

From: benh If you really need to some how pull each in to eachother then this was
the only way I could get things to work:

[My::A]
package My::A;
use Moose;
has b => (
is => 'rw',
isa => 'My::B',
lazy =>1,
default => sub{
use My::B;
My::B->new;
}
);
sub kitten { return 'cute' };
1;

[My::B]
package My::B;
use Moose;
has a => (
is => 'rw',
isa => 'My::A',
lazy => 1,
default => sub{
use My::A;
My::A->new;
}
);
sub hello {return 'world';}
1;

[AB.pl]
#!/usr/bin/perl
use strict;
use warnings;
use Test::More qw{no_plan};
use My::A;
my $a = My::A->new;
is( $a->b->hello, 'world'); #PASS
is( $a->b->a->kitten, 'cute'); #PASS




On 7/2/08, benh <ben.hengst@gmail.com> wrote:
> I'm with Chris, this is more of a design issue. What is the common
> part between A and B that could not be pulled out to a role?
>
>
> On 7/2/08, Chris Prather <chris@prather.org> wrote:
> > On Wed, 2 Jul 2008 17:22:44 -0700, Christopher Brown wrote:
> > > Hi All,
> > >
> > > What is the best way to moosify an existing CPAN class and all the classes
> > > called by this class. I know that *extends* works:
> > >
> > > package MooseX::Module::A;
> > > use Moose;
> > > extends 'Module::A';
> > >
> > >
> > > package MooseX::Module::B;
> > > use Moose;
> > > extends 'Module::B';
> > >
> > > sub my_b_extension {
> > > ...
> > > }
> > >
> > >
> > > But how do you extend both modules when Module::A relies on and calls
> > > Module::B? Such as.
> > >
> > > package Module::A;.
> > >
> > > sub create_b {
> > > my $self = shift;
> > > $self->{b} = Module::B->new();
> > > }
> > >
> > > ...
> > >
> > > Now in:
> > >
> > > package main;
> > > use MooseX::Module::A;
> > > use MooseX::Module::B;
> > >
> > > my $a = Moose::X::Module::A->new(); # Cool
> > > $a->create_b; # Cool
> > > $a->{b}->my_b_extension(); # FAIL!
> > >
> > > In this scenario, I will not see *my_b_extension*. In normal, non-Moose
> > > Perl, I would:
> > >
> > > package Module::AX;
> > > use *base* 'Module::A';
> > > ...
> > >
> > > package Module::BX;
> > > use *base* 'Module::B';
> > > ...
> > >
> >
> >
> > Well base.pm and moose play fairly nice together ... but I'm not sure
> > even base.pm would solve this ...
> >
> > $self->{b} = Module::B->new(); # you hardcode the module name here ...
> > nothing can save you now
> >
> > you'd need to override the create_b method in MX::Module::A ... which
> > you'd have to do in any perl code because you've hardcoded the
> > classname in the method. This isn't a Moose problem, this is a crappy
> > design decision problem.
> >
> > If you want to be able to subclass Module::B ... then create_b either
> > needs to make the classname for B configurable (via a parameter to the
> > method, or an attribute in A or something...) or you need to override
> > it in your subclass of A to call the class you need ... (or you
> > override it with something configurable).
> >
> >
> > -Chris
> >
>
>
>
> --
>
> benh~
>


--
benh~

2008-07-02T20:39:06Z
Re: Extends type questions by benh

From: benh I'm with Chris, this is more of a design issue. What is the common
part between A and B that could not be pulled out to a role?

On 7/2/08, Chris Prather <chris@prather.org> wrote:
> On Wed, 2 Jul 2008 17:22:44 -0700, Christopher Brown wrote:
> > Hi All,
> >
> > What is the best way to moosify an existing CPAN class and all the classes
> > called by this class. I know that *extends* works:
> >
> > package MooseX::Module::A;
> > use Moose;
> > extends 'Module::A';
> >
> >
> > package MooseX::Module::B;
> > use Moose;
> > extends 'Module::B';
> >
> > sub my_b_extension {
> > ...
> > }
> >
> >
> > But how do you extend both modules when Module::A relies on and calls
> > Module::B? Such as.
> >
> > package Module::A;.
> >
> > sub create_b {
> > my $self = shift;
> > $self->{b} = Module::B->new();
> > }
> >
> > ...
> >
> > Now in:
> >
> > package main;
> > use MooseX::Module::A;
> > use MooseX::Module::B;
> >
> > my $a = Moose::X::Module::A->new(); # Cool
> > $a->create_b; # Cool
> > $a->{b}->my_b_extension(); # FAIL!
> >
> > In this scenario, I will not see *my_b_extension*. In normal, non-Moose
> > Perl, I would:
> >
> > package Module::AX;
> > use *base* 'Module::A';
> > ...
> >
> > package Module::BX;
> > use *base* 'Module::B';
> > ...
> >
>
>
> Well base.pm and moose play fairly nice together ... but I'm not sure
> even base.pm would solve this ...
>
> $self->{b} = Module::B->new(); # you hardcode the module name here ...
> nothing can save you now
>
> you'd need to override the create_b method in MX::Module::A ... which
> you'd have to do in any perl code because you've hardcoded the
> classname in the method. This isn't a Moose problem, this is a crappy
> design decision problem.
>
> If you want to be able to subclass Module::B ... then create_b either
> needs to make the classname for B configurable (via a parameter to the
> method, or an attribute in A or something...) or you need to override
> it in your subclass of A to call the class you need ... (or you
> override it with something configurable).
>
>
> -Chris
>


--
benh~

2008-07-02T20:29:09Z
Re: Extends type questions by Chris Prather

From: Chris Prather On Wed, 2 Jul 2008 17:22:44 -0700, Christopher Brown wrote:
> Hi All,
>
> What is the best way to moosify an existing CPAN class and all the classes
> called by this class. I know that *extends* works:
>
> package MooseX::Module::A;
> use Moose;
> extends 'Module::A';
>
>
> package MooseX::Module::B;
> use Moose;
> extends 'Module::B';
>
> sub my_b_extension {
> ...
> }
>
>
> But how do you extend both modules when Module::A relies on and calls
> Module::B? Such as.
>
> package Module::A;.
>
> sub create_b {
> my $self = shift;
> $self->{b} = Module::B->new();
> }
>
> ...
>
> Now in:
>
> package main;
> use MooseX::Module::A;
> use MooseX::Module::B;
>
> my $a = Moose::X::Module::A->new(); # Cool
> $a->create_b; # Cool
> $a->{b}->my_b_extension(); # FAIL!
>
> In this scenario, I will not see *my_b_extension*. In normal, non-Moose
> Perl, I would:
>
> package Module::AX;
> use *base* 'Module::A';
> ...
>
> package Module::BX;
> use *base* 'Module::B';
> ...
>

Well base.pm and moose play fairly nice together ... but I'm not sure
even base.pm would solve this ...

$self->{b} = Module::B->new(); # you hardcode the module name here ...
nothing can save you now

you'd need to override the create_b method in MX::Module::A ... which
you'd have to do in any perl code because you've hardcoded the
classname in the method. This isn't a Moose problem, this is a crappy
design decision problem.

If you want to be able to subclass Module::B ... then create_b either
needs to make the classname for B configurable (via a parameter to the
method, or an attribute in A or something...) or you need to override
it in your subclass of A to call the class you need ... (or you
override it with something configurable).

-Chris

2008-07-02T19:47:51Z
Extends type questions by Christopher Brown

From: Christopher Brown Hi All,

What is the best way to moosify an existing CPAN class and all the classes
called by this class. I know that *extends* works:

package MooseX::Module::A;
use Moose;
extends 'Module::A';


package MooseX::Module::B;
use Moose;
extends 'Module::B';

sub my_b_extension {
...
}


But how do you extend both modules when Module::A relies on and calls
Module::B? Such as.

package Module::A;.

sub create_b {
my $self = shift;
$self->{b} = Module::B->new();
}

...

Now in:

package main;
use MooseX::Module::A;
use MooseX::Module::B;

my $a = Moose::X::Module::A->new(); # Cool
$a->create_b; # Cool
$a->{b}->my_b_extension(); # FAIL!

In this scenario, I will not see *my_b_extension*. In normal, non-Moose
Perl, I would:

package Module::AX;
use *base* 'Module::A';
...

package Module::BX;
use *base* 'Module::B';
...

Thanks in Advance,

Chris

2008-07-02T17:22:53Z
MooseX::AttributeHelpers 0.11 by Sartak

From: Sartak Hi again,

(Sorry, forgot to include this in the previous mail!)

MooseX::AttributeHelpers 0.11 has a great new features, thanks to
Jason May. You can easily curry in arguments for the created methods.

Here's a simplistic example.

package Class;
has 'foo' => (
metaclass => 'Number',
is => 'rw',
curries => {
set => {
zero_foo => [ 0 ],
one_foo => [ 1 ],
},
mul => {
double_foo => [ 2 ],
triple_foo => [ 3 ],
},
div => {
oh_shit => [ 0 ],
},
},
);

Class->zero_foo; # start at 0
Class->one_foo; # set to 1
Class->triple_foo; # set to 3
Class->triple_foo; # set to 9
Class->halve_foo; # set to 4.5
Class->oh_shit; # explodes because 4.5 / 0 is an error :)

It's pretty nifty! Especially because you can now have multiple
curried methods of one type (see how I have two methods for "set" and
"mul").

Shawn M Moore

__END__

0.11 Thurs. Jun 26, 2008
- add the ability to curry method providers (thanks to jasonmay)
- Counter: add set and allow inc and dec to accept args
- add Bool as an attribute helper (thanks to jasonmay)
- bump all modules to version 0.11 for consistency (sartak)

2008-06-27T13:41:16Z
Moose 0.51 by Sartak

From: Sartak Hi gang,

I uploaded Moose 0.51 to CPAN last night. (I didn't upload a new
Class::MOP because there were only very minor tweaks)

There's a new feature, BUILDARGS. It lets you munge whatever is passed
to ->new. You can now accept any kind of parameters you want; you only
need to return a hashref. This is more convenient than wrapping new,
and it also lets Moose inline the constructor when you make_immutable.

nothingmuch came up with the idea and implementation in record time.
You may have noticed a bunch of MooseX releases -- these were because
if you create an inlined constructor (for immutable), you need to
start taking into account BUILDARGS.

There were some other good changes. Keep on Moosin'!

Shawn M Moore

__END__

0.51 Thurs. Jun 26, 2008
* Moose::Role
- add unimport so "no Moose::Role" actually does
something (sartak)

* Moose::Meta::Role::Application::ToRole
- when RoleA did RoleB, and RoleA aliased a method from RoleB in
order to provide its own implementation, that method still got
added to the list of required methods for consumers of
RoleB. Now an aliased method is only added to the list of
required methods if the role doing the aliasing does not
provide its own implementation. See Recipe 11 for an example
of all this. (Dave Rolsky)
- added tests for this

* Moose::Meta::Method::Constructor
- when a single argument that wasn't a hashref was provided to
an immutabilized constructor, the error message was very
unhelpful, as opposed to the non-immutable error. Reported by
dew. (Dave Rolsky)
- added test for this (Dave Rolsky)

* Moose::Meta::Attribute
- added support for meta_attr->does("ShortAlias") (sartak)
- added tests for this (sartak)
- moved the bulk of the `handles` handling to the new
install_delegation method (Stevan)

* Moose::Object
- Added BUILDARGS, a new step in new()

* Moose::Meta::Role::Application::RoleSummation
- fix typos no one ever sees (sartak)

* Moose::Util::TypeConstraints
* Moose::Meta::TypeConstraint
* Moose::Meta::TypeCoercion
- Attempt to work around the ??{ } vs. threads issue
- Some null_constraint optimizations

2008-06-27T13:11:57Z
Re: [Moose eats exports] The Moose seems extra hungry today? by Stevan Little

From: Stevan Little Benh,

An imported sub is not a method, Roles only deal with methods.

So in the first test the looks_like_number is only available as a
function in the role package itself and not in My::Class since the
role composition sees that it is imported from Scalar::Util and not
defined in the role itself.

In the second one, the import method is created by Exporter and
therefore *should* be composed into My::Class2 however I suspect that
&import would, if you were to introspect it have a package of
"Exporter" and a name of "__ANON__" and so Moose role composition
would ignore it. Also, this wouldn't work as expected anyway because
with 'My::Role' does not call ->import it only loads the role package
with require.

In the 3rd example with extends, you are not inheriting the exports
so you cannot call it as looks_like_number and have Perl's sub
dispatcher find it. However you could call it as a method $self-
>look_like_number and have Perls method dispatcher find it. However
this is not very useful since $self will never be a number and will
be the first arg passed to look_like_number.

In the 4th example, your My::Ext2 class will actually inherit the
import method, so if you were to do:

package Foo;
use My::Ext2;

Then looks_like_number would actually get imported into Foo. However,
as with roles, when you do extends 'My::Base' it will not call
My::Base->import and so never import the looks_like_number function.

As I mentioned on IRC, apparently Spiffy used to do this, and Ingy
mentioned at YAPC that he would like to write a MooseX:: module to do
the same. It would be fairly simple and would take some work on your
part to determine what is imported and what is not, but all the tools
are there for you (Class::MOP::Package symbol table introspection
will help a lot, along with the Class::MOP::get_code_info util sub).

- Stevan

On Jun 23, 2008, at 7:37 PM, benh wrote:

> So I'm sure that this is due to my lack of understating on how Objects
> are built behind the fur but it seems that if I use something in a
> role that I should use it in the caller, same with a base class with a
> sub class? Have I completely missed something obvious?
>
> I've written up a test to illustrate the point. Sadly all the tests
> pass (throws_ok) ?
>
> http://develonizer.com/svn/misc/role_use.t
>
>
> --
> benh~

2008-06-23T16:51:30Z
[Moose eats exports] The Moose seems extra hungry today? by benh

From: benh So I'm sure that this is due to my lack of understating on how Objects
are built behind the fur but it seems that if I use something in a
role that I should use it in the caller, same with a base class with a
sub class? Have I completely missed something obvious?

I've written up a test to illustrate the point. Sadly all the tests
pass (throws_ok) ?

http://develonizer.com/svn/misc/role_use.t


--
benh~

2008-06-23T16:37:33Z
Re: Several Questions by Chris Prather

From: Chris Prather >
> A frightening suggestion is to look at Moose::Tiny. You should be able
> to subclass it to give the pre-defined types you want (or possibly look
> them up) ... but I'm not sure this would do the lookup into a per-class
> module (::user ::password) ... it's currently set up to give the
> closest approximation to what Object Tiny defaults to.
>
> -Chris

And I just looked at it myself, it's not as simple as a "simple
subclass" ... but I could make it that simple trivially. Just need to
extract the actual attribute construction into a method that import()
calls.

-Chris

2008-06-23T16:35:14Z
Re: Several Questions by Chris Prather

From: Chris Prather On Mon, 23 Jun 2008 15:20:32 -0700, Christopher Brown wrote:
> Stevan et al.,
>
> Thanks. That is exactly what I want to do. I will take a look at
> MooseX::Storage and read on how the Moose exports works. ( It might be a
> little foreign to me since I am an Exporter guy. I know, I know. I may
> lean again on the list for another questions or so. but I will give it my
> best shot. )
>
> Okay ... MooseX::Common is a little weak. MooseX::Getopt::Commom?
> MooseX::Attributes::Common? MooseX::CommonAttributes? MooseX::Attributes?
>
> I'll have to sleep on this one. As you can see, I have more than a little
> trepidation of picking a stoopid name.
>
> Cheers,
>
> Chris


A frightening suggestion is to look at Moose::Tiny. You should be able
to subclass it to give the pre-defined types you want (or possibly look
them up) ... but I'm not sure this would do the lookup into a per-class
module (::user ::password) ... it's currently set up to give the
closest approximation to what Object Tiny defaults to.

-Chris

2008-06-23T16:32:10Z
Re: Several Questions by Christopher Brown

From: Christopher Brown Stevan et al.,

Thanks. That is exactly what I want to do. I will take a look at
MooseX::Storage and read on how the Moose exports works. ( It might be a
little foreign to me since I am an Exporter guy. I know, I know. I may
lean again on the list for another questions or so. but I will give it my
best shot. )

Okay ... MooseX::Common is a little weak. MooseX::Getopt::Commom?
MooseX::Attributes::Common? MooseX::CommonAttributes? MooseX::Attributes?

I'll have to sleep on this one. As you can see, I have more than a little
trepidation of picking a stoopid name.

Cheers,

Chris



On Mon, Jun 23, 2008 at 7:52 AM, Stevan Little <
stevan.little@iinteractive.com> wrote:

> Well,
>
> You could do like what we did with MooseX::Storage, which exports a Storage
> function such that:
>
> with Storage(format => 'JSON', io => 'File');
>
> is equivalent to:
>
> with 'MooseX::Storage::Basic', 'MooseX::Storage::Format::JSON',
> 'MooseX::Storage::IO::File';
>
> So you could export an 'opts' function which would do the role composition
> for you, such that ...
>
> opts qw(user password);
>
> would be equivalent to:
>
> with 'My::App::User', 'My::App::Password';
>
> as for if this would be useful for CPAN, I think if you