RE: Moose Type Constraints violations to warnings?

[email protected] (Edward Allen)
Newsgroups perl.moose
Message-ID <[email protected]>
Looks like the code was mangled.  Look at attached.

---
Edward J. Allen III




> From: [email protected]
> To: [email protected]
> Subject: RE: Moose Type Constraints violations to warnings?
> Date: Fri, 10 Jun 2011 12:41:41 -0700
> 
> 
> it seems to me that you have two problems:
> 1)  You want to know that your value is always a number, so you add a constraint.
> 2)  Your users will not always enter the correct value.
> 3)  You want to KNOW what the bad value was.
> So I would separate out the input attribute and the used attribute.  Moose (and mouse) makes this easy!  Check out this example (I wrote it using 5.10 Perl, mainly as I am trying to practice using it...):
> 
> #### Start
> use Mouse;use Mouse::Util::TypeConstraints;package MyApp::Room;use Carp qw(cluck);use Scalar::Util qw(looks_like_number);
> use feature 'switch';
> # Subtype and coercionsubtype 'Price'    => as 'Num';
> coerce 'Price'    => from 'Str'    => via {        given($_) {            # Anything like a number is OK            when (looks_like_number $_) {                return $_;            }            # $9.99  is ok.            when(/ \A \$(\d+\.?\d+?) \z /xms) {                return $1;            }            # $.99 is ok            when(/ \A \$(\d+?\.\d+) \z /xms) {                return $1;            }            # Complain about anything else.            default {                cluck 'Price must be a number!  Setting to $0.00';                return 0;            }         }     };
> has 'price_in' => (    is => 'rw',    perdicate => 'has_price_in',    trigger => sub {        my ($self,$val) = @_;        $self->price($val);    });
> has 'price' => (    is => 'rw',    isa => 'Price',    coerce => 1,);
> 
> package main;
> use feature 'say';
> # Says 3.50my $room = MyApp::Room->new( price_in => '3.50' );say "Room price: " . $room->price();
> # Says 1000$room->price_in('1000');say "Room price: " . $room->price();
> # Says 0 and complains$room->price_in('cheap');say "Room price: " . $room->price();
> 
> 
> #### END
> ---
> Edward J. Allen III
> 
> 
> 
> 
> > Date: Fri, 10 Jun 2011 13:37:36 -0400
> > Subject: Re: Moose Type Constraints violations to warnings?
> > From: [email protected]
> > To: [email protected]
> > CC: [email protected]; [email protected]
> > 
> > On Fri, Jun 10, 2011 at 1:14 PM, Buddy Burden <[email protected]> wrote:
> > > Ovid,
> > >
> > > On Fri, Jun 10, 2011 at 3:06 AM, Ovid <[email protected]> wrote:
> > >> When I declare a parameter as follows:
> > >>
> > >>
> > >>     has 'some_val' => (
> > >>         is  => 'rw',
> > >>         isa => 'Int',
> > >>     );
> > >>
> > >> Later if I do $object->some_value("foobar"), it blows up with a stack trace because of the type constraint violation.
> > >>
> > >> Without using signal handlers, is there some way I can convert that exception into a warning except when something like $ENV{HARNESS_ACTIVE} is true? Preferably on a per-attribute basis?
> > >
> > > Is it possible that Jesse's answer to my question here:
> > >
> > >    http://www.mail-archive.com/[email protected]/msg01464.html
> > >
> > > could help?  I know it isn't exactly the same problem that you're
> > > describing, but it seems that if there's a way to solve one, there
> > > must be a way to solve the other as well.  Possibly the code of the
> > > module he mentions would be illuminating.
> > >
> > > Apologies if this isn't actually helpful.
> > 
> > Karen also suggested MooseX::Constructor::AllErrors but discarded it
> > because it was Moose only. A Mouse port would probably be pretty
> > simple.
> > But it only covers the constructor case.
> > 
> > For accessors, if the issue is that you "don't want type constraints
> > to throw out *everything*" you'll need to show a better example of the
> > parsing code because I'm not sure how a judicious use of Try::Tiny
> > wouldn't be the natural solution there. Accessors never really operate
> > on the entire object, so you'd only throw an exception for a specific
> > attribute. Wrapping the block in Try::Tiny will leave the object in a
> > partial state (whatever had been mutated until the exception was
> > thrown) and give you an error message you could then dispatch with.
> > 
> > The particular phrase Ovid referred to in the Moose docs was written a
> > *long* time ago when Stevan still believed that you could potentially
> > safely turn off runtime type checks. My impression is that he's
> > re-considered this idea now. It also applies to Moose and not Mouse.
> > Mouse has it's own development community and goals.
> > 
> > -Chris
>
testhas.pl (text/plain, 1.3 KB)
package MyApp::Room;
use Mouse;
use Mouse::Util::TypeConstraints;
use Carp qw(cluck);
use Scalar::Util qw(looks_like_number);

use feature 'switch';

# Subtype and coercion
subtype 'Price'
    => as 'Num';


coerce 'Price'
    => from 'Str'
    => via { 
        given($_) {                 
            # Anything like a number is OK
            when (looks_like_number $_) {     
                return $_;
            }
            # $9.99  is ok.
            when(/ \A \$(\d+\.?\d+?) \z /xms) {
                return $1;
            }
            # $.99 is ok
            when(/ \A \$(\d+?\.\d+) \z /xms) {
                return $1;
            }
            # Complain about anything else.
            default {
                cluck 'Price must be a number!  Setting to $0.00';
                return 0;
            }
         }
     };

has 'price_in' => (
    is => 'rw',
    perdicate => 'has_price_in',
    trigger => sub {
        my ($self,$val) = @_;
        $self->price($val);
    }
);

has 'price' => (
    is => 'rw',
    isa => 'Price',
    coerce => 1,
);


package main;

use feature 'say';

my $room = MyApp::Room->new( price_in => '3.50' );

say "Room price: " . $room->price();

$room->price_in('1000');

say "Room price: " . $room->price();

$room->price_in('cheap');

say "Room price: " . $room->price();
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.