Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Moo-Type checking example from Perl Maven: What should be the expected result?

by Perl300 (Friar)
on Sep 28, 2018 at 22:05 UTC ( [id://1223262]=perlquestion: print w/replies, xml ) Need Help??

Perl300 has asked for the wisdom of the Perl Monks concerning the following question:

I was going through the perl maven web resource and from the example about type checking:

examples/mootype/Person.pm

package Person; use Moo; has name => (is => 'rw'); has age => ( is => 'rw', isa => sub { die "'$_[0]' is not an integer!" if $_[0] !~ /^\d+$/; }, ); 1;

examples/mootype/student_1.pl

use strict; use warnings; use 5.010; use Person; my $student = Person->new( name => 'Foo', age => 22 ); say $student->name; say $student->age; $student->age('young'); say $student->age;

The expected result stated on the site is that

Foo

22

isa check for "age" failed: 'young' is not an integer! at Person.pm line 8.

But what I get is

isa check for "age" failed: '22' is not an integer! at ~/bin/../lib/Person.pm line 10.

What I am trying to understand is, has something changed and this result (no presence of first two say) is now expected? Or am I somehow doing it different? I am using same code including `use 5.010` but the version of perl I am on is 5.26.1 and I have added following two lines between `use 5.010` and `use Person`

use FindBin qw($Bin);

use lib "$Bin/../lib";

Replies are listed 'Best First'.
Re: Moo-Type checking example from Perl Maven: What should be the expected result?
by 1nickt (Canon) on Sep 29, 2018 at 02:08 UTC

    Hi, Moo's a great choice. Also good to learn by doing, e.g. by writing your own simple isa type validator. But as ++choroba says you probably made a typo in your code, a "type typo" I guess. But that's a good illustration of one good reason to use libraries for common functionality. In the case of Moo type checking we have a very powerful and easy to use system in Type::Tiny.

    Your code could be rewritten as

    package Person; use Moo; use Types::Standard 'Int'; has name => (is => 'rw'); has age => (is => 'rw', isa => Int ); 1;
    The output is more verbose:
    perl -I. 1223262.pl Foo 22 Value "young" did not pass type constraint "Int" (in $self->{"age"}) a +t 1223262.pl line 9 "Int" is a subtype of "Num" "Num" is a subtype of "LaxNum" Value "young" did not pass type constraint "LaxNum" (in $self->{"a +ge"}) "LaxNum" is defined as: (defined($_) && !ref($_) && Scalar::Util:: +looks_like_number($_))
    If you want to control the message, you can, by declaring the type yourself. (This would also allow you to disallow people who haven't been born yet!) See Type::Library for more info on that.

    Hope this helps!


    The way forward always starts with a minimal test.

      Thanks for the advertisement. :)

      I'll also point out that /^\d+$/ isn't a great integer check. \d allows more characters than the digits 0 to 9. It also allows a whole bunch of other Unicode digit characters, which 99% of the time, you probably didn't really intend to allow. So use /^[0-9]+$/ which is barely any more typing.

      I'll also just give a quick demo of:

      package Person; use Moo; use Types::Standard 'Int'; has name => (is => 'rw'); has age => (is => 'rw', isa => Int->where(q{ $_ > 0 })); 1;

      ... as a simple way to prohibit negative integers. Or even:

      package Person; use Moo; use Types::Common::Numeric 'PositiveInt'; has name => (is => 'rw'); has age => (is => 'rw', isa => PositiveInt); 1;

      Or:

      package Person; use Moo; use Types::Common::Numeric 'IntRange'; has name => (is => 'rw'); has age => (is => 'rw', isa => IntRange[0,200]); # 200 is a realisti +c age limit 1;
        So use /^[0-9]+$/ which is barely any more typing.

        Quite right. There's also an even shorter alternative: /^\d+$/a which uses the handy /a modifier. This has the added benefit of enforcing ASCII restriction on some other classes too, should they be used in the regex.

Re: Moo-Type checking example from Perl Maven: What should be the expected result?
by choroba (Cardinal) on Sep 28, 2018 at 22:24 UTC
    Are you sure you copied the code correctly? I'm getting the expected error. To get the error about 22, I had to change !~ to =~, or change the if to unless.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Moo-Type checking example from Perl Maven: What should be the expected result?
by NetWallah (Canon) on Sep 29, 2018 at 05:09 UTC
    'say' puts stuff to STDOUT.

    'die' spews to STDERR.

    Since outputs are to different devices, the order may be intermingled - usually, STDERR output appears first.

    You could get your expected output by using 'warn' instead of 'say' (and adding "\n").

                    Memory fault   --   brain fried

Re: Moo-Type checking example from Perl Maven: What should be the expected result?
by Perl300 (Friar) on Oct 01, 2018 at 15:24 UTC
    Thank you all for your valuable inputs which as always helped me in my learning efforts. Journey continues :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1223262]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-04-19 22:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found