Re: Multiple coercions ?

2008-09-24 Thread Charles Alderman
I apologize, I don't mean any offense by "newbie".  It was not my  
intent to label you that way.  I was only referring to the category of  
questions that are easy to resolve.  In regards to Moose, I consider  
myself a newbie, as opposed to the "experts" who created it and  
contribute to it.


Thanks,
Charles Alderman

- Original Message -
From: Alexis Sukrieh <[EMAIL PROTECTED]>
Sent: Wed, 24 Sep 2008 17:41:02 +0200
Re: Re: Multiple coercions ?




Charles Alderman a écrit :
Perhaps if a user happens to overlook the version they're running   
before asking a question, it could be accepted as a newbie question  
 in a moose-users list conversation.


It's really funny how you can be flagged "newbie" at the first mistake
you make.

Indeed, I totally forgot that Moose grows so quickly that my fresh
_stable_ Ubuntu system would be far too old for a bug-proof version of
Moose.

Indeed, this is my fault. I apology for that.

But please don't start to judge people with the first email/mistake you
see from them.

You don't want to do that.


Alexis.






Re: Multiple coercions ?

2008-09-24 Thread Charles Alderman

Meta questions:

Is the purpose of this list to only report bugs or discuss design  
questions?  Or is it to help out Moose users?  Should the list be  
split into moose-dev and moose-users?


Perhaps if a user happens to overlook the version they're running  
before asking a question, it could be accepted as a newbie question in  
a moose-users list conversation.


Thanks,
Charles Alderman

- Original Message -
From: Dave Rolsky <[EMAIL PROTECTED]>
Sent: Wed, 24 Sep 2008 10:14:49 -0500 (CDT)
Re: Re: Multiple coercions ?


Ok, Moose _0.58_ was just released, and you're reporting bugs in 0.31,
which was released approximately 10 months ago?

Why?


-dave

/*==
VegGuide.Org
Your guide to all that's veg
==*/






Re: Multiple coercions ?

2008-09-24 Thread Charles Alderman


I tried running that code.

My output:

% perl multiple_coercions.t

ok 1 - date set to 2008-09-12
ok 2 - coerce date_time from date
ok 3 - date_time correctly coerced
ok 4 - coerce from Int
1..4

Also:

% perl -Moose -e"print $Moose::VERSION"

0.54

Thanks,
Charles Alderman


- Original Message -
From: Alexis Sukrieh <[EMAIL PROTECTED]>
Sent: Wed, 24 Sep 2008 16:57:11 +0200
Re: Re: Multiple coercions ?




Alexis Sukrieh a écrit :

Find attached the test script:


Hmm, sorry, looks like the attachment gets droped by the ML.
Here is the pure paste:


$ cat multiple_coercions.t

use Test::More 'no_plan';
use strict;
use warnings;

sub time_to_datetime($) {
my $time = shift;
my ($sec, $min, $hour, $day, $mon, $year) = localtime($time);
$mon++;
$year += 1900;
$sec = sprintf('%02d', $sec);
$min = sprintf('%02d', $min);
$hour = sprintf('%02d', $hour);
$mon = sprintf('%02d', $mon);
$day = sprintf('%02d', $day);
return "${year}-${mon}-${day} ${hour}:${min}:${sec}";
}

# Types & Coercions
use Moose::Util::TypeConstraints;

subtype 'Date'
=> as 'Str'
=> where { /^\d\d\d\d-\d\d-\d\d$/ };

subtype 'DateTime'
=> as 'Str'
=> where { /^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$/ };

coerce 'DateTime'
=> from 'Int'
=> via { time_to_datetime($_) };

coerce 'DateTime'
=> from 'Date'
=> via { "$_ 00:00:00" };

{
package Foo;
use Moose;

has 'date' => (
is => 'rw',
isa => 'Date',
);

has 'date_time' => (
is => 'rw',
isa => 'DateTime',
coerce => 1,
);
}

# fixtures
my $date  = '2008-09-12';
my $date_time =  '2008-09-12 00:00:00';

my $o = Foo->new;
is( $date, $o->date($date), "date set to $date" );
ok( $o->date_time($o->date), 'coerce date_time from date' );
is( $date_time, $o->date_time, 'date_time correctly coerced' );

ok( $o->date_time( time ), 'coerce from Int' );






Re: Multiple coercions ?

2008-09-24 Thread Charles Alderman



Now - and that's where the issue gets in the scene - if I add another
coercion for the DateTime subtype, but from another source, it won't
work :


Are you sure you haven't defined the coercion to "DateTime" from "Int"  
somewhere else?


This works for me:

{
package Foo;
use Moose;
use Moose::Util::TypeConstraints;

subtype 'Date'
  => as 'Str'
  => where { /^\d\d\d\d-\d\d-\d\d$/ };

subtype 'DateTime'
  => as 'Str'
  => where { /^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$/ };

coerce 'DateTime'
  => from 'Date'
  => via { "$_ 00:00:00" };

coerce 'DateTime'
  => from 'Int'
  => via { '2008-09-24 00:00:00' };

has 'date' => (
is => 'rw',
isa => 'Date',
    );

    has 'date_time' => (
is => 'rw',
isa => 'DateTime',
coerce => 1,
);
}

{

  my $f = Foo->new;
  $f->date_time(1234);
  $f->date_time('2008-09-24');

}

Thanks,
Charles Alderman



Re: Coercions and custom type parameters

2008-07-25 Thread Charles Alderman

- Original Message -
From: Yuval Kogman <[EMAIL PROTECTED]>
Sent: Thu, 24 Jul 2008 23:27:11 +0300
Re: Re: Coercions and custom type parameters


Declaring an attribute with a parameterized type:

has foo => (
isa => "ArrayRef[Foo]",
coerce => 1,
);

has a specific behavior right now, it enables only the coercions on
the type "ArrayRef[Foo]".




OK, I hadn't thought about it that way.  So, I can declare a subtype  
that looks parametrized, but it really isn't.


subtype 'ArrayRef[Int]' => as 'Str' => where { 1 };




Custom parametrized types could still make sense though:

MyCustomType[Foo]

is a useful construct for custom container types, for functors, etc
etc, so deep_coerce *is* a useful property to have



Wow, I didn't know that was possible either.  You guys have thought of  
everything...


So, this is my custom collection, which is parameterizable:

  subtype 'BigArrayRef' => as 'ArrayRef' => where { scalar(@$_) > 1 };

  has 'my_big_arrayref' => ( is => 'rw', isa => 'BigArrayRef[Int]' );


Now, I can also create a pseudo parameterizable subtype, that does  
something like this:


  subtype 'BigArrayRef[Int] => as 'ArrayRef' => where {
  my $ar = $_;
  return unless scalar( @$ar ) > 1;
  for ( @$ar ) {
return unless m/^ \d+ $/x;
  }
  return 1;
  }

Well what does this mean now:

has 'my_new_big_arrayref' => ( is => 'rw', isa => 'BigArrayRef[Int][Int]' );

I think I've just confused myself.  I'm going to sit down and play  
with this some more...


Thanks,
Charles Alderman





Re: Coercions and custom type parameters

2008-07-24 Thread Charles Alderman
I guess that if you're trying to prevent this as an action at a  
distance, 'deep_coerce' wouldn't really be acceptable either.   
Wouldn't that just be a more explicit warning of an action at a  
distance?


If moose type constraints become too complicated, I guess at some  
point, a designer/developer just needs to turn the parametrized type  
into its own class.  So, maybe I'm answering my own question here.


At any rate, I'll look more at the mailing list archives...

Thanks,
Charles Alderman

- Original Message -
From: Yuval Kogman <[EMAIL PROTECTED]>
Sent: Thu, 24 Jul 2008 22:37:45 +0300
Re: Re: Coercions and custom type parameters




This has been brought up before, the short story is 'coerce => 1'
may introduce action at a distance, so we decided that if at all
this should be 'deep_coerce => 1'.

At any rate, this is a little trickier than it sounds, but if Stevan
approves deep_coerce => 1 feel free to commit this as a todo test
and start hacking away.

Regards,
Yuval

On Thu, Jul 24, 2008 at 15:20:13 -0400, Charles Alderman wrote:

Hello Moose,

I guess I have an enhancement idea/request.

I have a parametrized ArrayRef[] of a custom type, I'd like my coercion on
that type to work for any of the values in the collection.  HashRef[]s
should work too.  Maybe Maybe[]s, but not in my example below.

Would this be worthwhile or viable?  If so, I'd be willing to attempt a
patch...

Thanks,
Charles Alderman


Here's a test:



#!/usr/bin/perl

use strict;
use warnings;

use Test::More tests => 2;
use Test::Exception;

{

  package Foo;
  use Moose;
  use Moose::Util::TypeConstraints;

  enum 'Foo::Values' => qw{ Foo Bar Baz None };
  coerce 'Foo::Values' => from 'Undef' => via { 'None' };

  has 'array_of_foo' => (
is => 'rw',
isa=> 'ArrayRef[Foo::Values]',
coerce => 1,
  );

}

{
  my $foo = Foo->new();

  my @ok_values = ( 'Foo', 'Bar', 'Baz', 'None' );
  my @coerced_values = ( 'Foo', 'Bar', undef, 'None' );

  lives_ok {
$foo->array_of_foo( [EMAIL PROTECTED] );
  }
  '... setting array with ok values';

  lives_ok {
$foo->array_of_foo( [EMAIL PROTECTED] );
  }
  '... setting array with coerced values';

}



--
  Yuval Kogman <[EMAIL PROTECTED]>
http://nothingmuch.woobling.org  0xEBD27418








Coercions and custom type parameters

2008-07-24 Thread Charles Alderman

Hello Moose,

I guess I have an enhancement idea/request.

I have a parametrized ArrayRef[] of a custom type, I'd like my  
coercion on that type to work for any of the values in the collection.  
 HashRef[]s should work too.  Maybe Maybe[]s, but not in my example  
below.


Would this be worthwhile or viable?  If so, I'd be willing to attempt  
a patch...


Thanks,
Charles Alderman


Here's a test:



#!/usr/bin/perl

use strict;
use warnings;

use Test::More tests => 2;
use Test::Exception;

{

  package Foo;
  use Moose;
  use Moose::Util::TypeConstraints;

  enum 'Foo::Values' => qw{ Foo Bar Baz None };
  coerce 'Foo::Values' => from 'Undef' => via { 'None' };

  has 'array_of_foo' => (
is => 'rw',
isa=> 'ArrayRef[Foo::Values]',
coerce => 1,
  );

}

{
  my $foo = Foo->new();

  my @ok_values = ( 'Foo', 'Bar', 'Baz', 'None' );
  my @coerced_values = ( 'Foo', 'Bar', undef, 'None' );

  lives_ok {
$foo->array_of_foo( [EMAIL PROTECTED] );
  }
  '... setting array with ok values';

  lives_ok {
$foo->array_of_foo( [EMAIL PROTECTED] );
  }
  '... setting array with coerced values';

}



Re: checking consistency between attributes

2008-07-16 Thread 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 <[EMAIL PROTECTED]>
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
<[EMAIL PROTECTED]> 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






Re: checking consistency between attributes

2008-07-14 Thread 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 <[EMAIL PROTECTED]>
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






Re: attribute w/ coerce and trigger - trigger arguments

2008-04-13 Thread Charles Alderman

Thanks Stevan,

I'm impressed by the quick turnaround, and I look forward to trying  
out the new release.


Charles Alderman
aldermania.com

- Original Message -
From: Stevan Little <[EMAIL PROTECTED]>
Sent: Sat, 12 Apr 2008 23:55:24 -0400
Re: Re: attribute w/ coerce and trigger - trigger arguments




Charles,

This bug has been fixed in svn
(http://code2.0beta.co.uk/moose/svn/Moose/trunk/) and will be in the
next release (coming soon, probably this week sometime).

- Stevan

On Apr 9, 2008, at 2:40 PM, Charles Alderman wrote:

Hello,

Just started using Moose (love it).  I recently spent a little time  
 struggling through an issue with trigger arguments for a coerced   
attribute.  So, I thought I'd post what I found here in case anyone  
 else runs into it.


Actually, I'm not sure if I found an undocumented feature of Moose,  
 or if it's a bug.  The docs say that a trigger is passed an  
updated  value of the attribute.  What happens is that if the  
attribute has  a coercion, the argument passed to the trigger  
hasn't been coerced.   So, technically, the argument isn't an  
updated value.  (At least,  that's where my confusion came from.)


The coerced value is still available to the trigger through the   
attribute's accessor, so maybe having the non-coerced value also   
available is for the best.


For clarification, I included an example.

Thanks,
Charles Alderman
aldermania.com

Versions:
Moose - 0.40
Class::MOP - 0.54

--

From the Moose perldoc:

The trigger option is a CODE reference which will be called after   
the value of the attribute is set. The CODE ref will be passed the   
instance itself, the **updated value** and the attribute   
meta-object (this is for more advanced fiddling and can typically   
be ignored).


--

Here's an example:
#This example is based on: Schwartz, R.L. "The Moose is Flying   
(part 2)". LinuxMag Column 95 (Jul 2007)


package Mortgage;

use Moose;
use Moose::Util::TypeConstraints;

use DateTime;
use DateTime::Format::DateManip;
use Date::Manip;
Date_Init( 'TZ=US/Eastern' );

subtype 'DateTime'
 => as 'Object'
 => where { $_->isa('DateTime') };

coerce 'DateTime'
 => from 'Str' => via {   
DateTime::Format::DateManip->parse_datetime($_) }

 => from 'HashRef' => via { DateTime->new(%$_) };

has 'closing_date' => (
 is => 'rw',
 isa => 'DateTime',
 coerce => 1,

 trigger => sub {
   my ( $self, $val, $meta ) = @_;
   print $self->closing_date->isa('DateTime') ? 'yes' : 'no';  # yes
   print $val->isa('DateTime')? 'yes' : 'no';  # no???
 }
);

1;

package main;

my $mtg = Mortgage->new( closing_date => 'yesterday' );
print $mtg->closing_date->isa('DateTime') ? 'yes' : 'no';  # yes








attribute w/ coerce and trigger - trigger arguments

2008-04-09 Thread Charles Alderman

Hello,

Just started using Moose (love it).  I recently spent a little time  
struggling through an issue with trigger arguments for a coerced  
attribute.  So, I thought I'd post what I found here in case anyone  
else runs into it.


Actually, I'm not sure if I found an undocumented feature of Moose, or  
if it's a bug.  The docs say that a trigger is passed an updated value  
of the attribute.  What happens is that if the attribute has a  
coercion, the argument passed to the trigger hasn't been coerced.  So,  
technically, the argument isn't an updated value.  (At least, that's  
where my confusion came from.)


The coerced value is still available to the trigger through the  
attribute's accessor, so maybe having the non-coerced value also  
available is for the best.


For clarification, I included an example.

Thanks,
Charles Alderman
aldermania.com

Versions:
Moose - 0.40
Class::MOP - 0.54

--

From the Moose perldoc:

The trigger option is a CODE reference which will be called after the  
value of the attribute is set. The CODE ref will be passed the  
instance itself, the **updated value** and the attribute meta-object  
(this is for more advanced fiddling and can typically be ignored).


--

Here's an example:
#This example is based on: Schwartz, R.L. "The Moose is Flying (part  
2)". LinuxMag Column 95 (Jul 2007)


package Mortgage;

use Moose;
use Moose::Util::TypeConstraints;

use DateTime;
use DateTime::Format::DateManip;
use Date::Manip;
Date_Init( 'TZ=US/Eastern' );

subtype 'DateTime'
  => as 'Object'
  => where { $_->isa('DateTime') };

coerce 'DateTime'
  => from 'Str' => via { DateTime::Format::DateManip->parse_datetime($_) }
  => from 'HashRef' => via { DateTime->new(%$_) };

has 'closing_date' => (
  is => 'rw',
  isa => 'DateTime',
  coerce => 1,

  trigger => sub {
my ( $self, $val, $meta ) = @_;
print $self->closing_date->isa('DateTime') ? 'yes' : 'no';  # yes
print $val->isa('DateTime')? 'yes' : 'no';  # no???
  }
);

1;

package main;

my $mtg = Mortgage->new( closing_date => 'yesterday' );
print $mtg->closing_date->isa('DateTime') ? 'yes' : 'no';  # yes