Giter Club home page Giter Club logo

p5-type-tiny's Introduction

p5-type-tiny's People

Contributors

aeruder avatar berekuk avatar book avatar bpj avatar chorny avatar cxw42 avatar dionys avatar djerius avatar dsteinbrunner avatar fschlich avatar haarg avatar haukex avatar ilmari avatar j1n3l0 avatar jonasbn avatar karpet avatar lucas1 avatar lucasbuchala avatar markstos avatar merrilymeredith avatar michal-josef-spacek avatar pmorch avatar robrwo avatar tobyink avatar windymelt avatar wlkdotcc avatar zoffixznet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

p5-type-tiny's Issues

InstanceOf["Type"] is not an object

I seem to remember this used to work, but either I have a brainworm or there's a bug. I would expect the second block of tests to work just the same as the first one, but InstanceOf['Path::Tiny']->check dies with Can't call method "check" on unblessed reference:

use 5.024;
use warnings;
use Test::More;
use Test::Fatal;
use Path::Tiny;     # just to be sure it's not a missing package, should probably work without
use Types::Standard qw( Str InstanceOf );

is( exception { Str->check("x") }, undef, "Str->check lives");
ok( Str->check("x"), "Str->check succeeds");

is( exception { InstanceOf['Path::Tiny']->check("x") }, undef, "InstanceOf['Path::Tiny']->check lives");
ok( ! InstanceOf['Path::Tiny']->check("x"), "InstanceOf['Path::Tiny']->check fails");

Using perl 5.32.1 and Types::Standard 1.012004

Test::Moose required by t/30-integration/Moose/native-attribute-traits.t

My cpanm Types/Standard.pm failed

t/30-integration/Moose/native-attribute-traits.t .......... Can't locate Test/Moose.pm in @INC (you may need to install the Test::Moose module) (@INC contains: ...) at t/30-integration/Moose/native-attribute-traits.t line 34.
BEGIN failed--compilation aborted at t/30-integration/Moose/native-attribute-traits.t line 34.
t/30-integration/Moose/native-attribute-traits.t .......... Dubious, test returned 2 (wstat 512, 0x200)

After I installed Test/Moose.pm it got installed ok.

Can't install on Perl 5.30

I get 1 failed test:

t/30-integration/Kavorka/80returntype.t ................... skipped: EXTENDED_TESTING

#   Failed test '... neither raise an exception'
#   at t/30-integration/Kavorka/basic.t line 55.
#          got: 'Undef did not pass type constraint "Int" at t/30-integration/Kavorka/basic.t line 43
#     "Int" is a subtype of "Int"
#     "Int" is a subtype of "Num"
#     "Num" is a subtype of "LaxNum"
#     "LaxNum" is a subtype of "Str"
#     "Str" is a subtype of "Value"
#     "Value" is a subtype of "Defined"
#     Undef did not pass type constraint "Defined"
#     "Defined" is defined as: (defined($_))
# '
#     expected: undef
# Looks like you failed 1 test of 2.

Sometimes "explain" is missing from Error::TypeTiny::Assertion

This code:

#!/usr/bin/perl -w
use strict;
use Type::Params qw(compile);
use Types::Standard qw(Dict Int);

for my $sub (
    sub {
        my $check = compile(Dict[key => Int]);
        $check->({ key => 'f' });
    },
    sub {
        compile(Dict[key => Int])->({ key => 'f' });
    },
    sub {
        my $check = compile(Dict[key => Int]);
        $check->({ key => 'f' });
    },
) {
    print "\n", "#" x 80, "\n";
    eval { $sub->() };
    print $@;
}

Produces this output:

################################################################################
Reference {"key" => "f"} did not pass type constraint "Dict[key=>Int]" (in $_[0]) at /home/peter/junk/explainMissing.pl line 20
################################################################################
Reference {"key" => "f"} did not pass type constraint "Dict[key=>Int]" (in $_[0]) at /home/peter/junk/explainMissing.pl line 20
    Reference {"key" => "f"} did not pass type constraint "Dict[key=>Int]" (in $_[0])
    "Dict[key=>Int]" constrains value at key "key" of hash with "Int"
    "Int" is a subtype of "Num"
    "Num" is a subtype of "LaxNum"
    Value "f" did not pass type constraint "LaxNum" (in $_[0]->{"key"})
    "LaxNum" is defined as: (defined($_) && !ref($_) && Scalar::Util::looks_like_number($_))

################################################################################
Reference {"key" => "f"} did not pass type constraint "Dict[key=>Int]" (in $_[0]) at /home/peter/junk/explainMissing.pl line 20
    Reference {"key" => "f"} did not pass type constraint "Dict[key=>Int]" (in $_[0])
    "Dict[key=>Int]" constrains value at key "key" of hash with "Int"
    "Int" is a subtype of "Num"
    "Num" is a subtype of "LaxNum"
    Value "f" did not pass type constraint "LaxNum" (in $_[0]->{"key"})
    "LaxNum" is defined as: (defined($_) && !ref($_) && Scalar::Util::looks_like_number($_))

I would have expected all these tree subs to produce the same $@ - but they don't. In addition, the first sub (without the explanation) is missing a newline. That has been fixed in pull-request #33.

Inherited coercions have too high priority

Migrated from rt.cpan.org #132392 (status was 'stalled')

Requestors:

From [email protected] on 2020-04-21 09:33:24
:

I'm having an issue with my Type::Tiny type library.

I have a type defined as a hashref with certain keys, defined with the Dict type. Some of those keys have their own types, with coercions, so i added coercion => 1 to the declaration of my type.

Now, I want to add a coercion to my type of hashref from a hashref with different keys. My coercion fails, b/c the inherited coercions are happening before the one that I defined myself.

Is this intended? If so, how can I work around the issue?

Types serialization / deserialization

I can't find proper way to serialize types.
I am trying to use "display_name" for serialization and eval for deserialization. But this works not for all parametrized types.

For example, StrMatch [qr/.../] can't be evaluated correctly.

Is it possible to add additional attribute, for example, serialize => sub {...}, so each type can correctly serialize yourself.

And additional Type::Tiny constructor method, than can create object from serialized value.

Tuple and ArrayRef are types of each other

Tuple->is_a_type_of(ArrayRef) # TRUE
ArrayRef->is_a_type_of(Tuple) # also TRUE

It doesn't make sense that Tuple would have Arrayref as a parent and ArrayRef to have Tuple as a parent (without time travel)...

I think its fine and is documented for Tuple->is_a_type_of(ArrayRef). But I will submit a test case and patch so that ArrayRef is not a child of Tuple, for your consideration.

Weird Perl <5.14 error with Union Types

Travis CI complained to me about all my builds using Perl less than 5.14. It only happens with a very particular combination of union types. I've narrowed it down to a unit test:

: perl -v
This is perl, v5.10.1 (*) built for darwin-2level
#!/usr/bin/env perl

use Test::More;
use Test::Fatal;

use Types::Standard -types;

is(
    exception { InstanceOf[ 'Foo::Bar' ] },
    undef,
    'InstanceOf worked',
);

is(
    exception { InstanceOf[ 'Foo::Bar' ] | Str },
    undef,
    'InstanceOf|Str worked',
);

is(
    exception { InstanceOf[ 'Foo::Bar' ] | HashRef },
    undef,
    'InstanceOf|HashRef worked',
);

is(
    exception { InstanceOf[ 'Foo::Bar' ] | HashRef | Str },
    undef,
    'InstanceOf|HashRef|Str worked',
);

done_testing;
ok 1 - InstanceOf worked
ok 2 - InstanceOf|Str worked
ok 3 - InstanceOf|HashRef worked
not ok 4 - InstanceOf|HashRef|Str worked
#   Failed test 'InstanceOf|HashRef|Str worked'
#   at lib/Starch/Store/DBI.pm line 29.
#          got: 'Can't locate object method "has_coercion" via package "Type::Tiny::_HalfOp" at /Users/aran/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Type/Tiny/Union.pm line 55.
# '
#     expected: undef
1..4
# Looks like you failed 1 test of 4.

[RFE] Strict[] type that only runs runs checks in strict mode

I have a lot of code like this:

use Devel::StrictMode;

...

has thing => (
    is => 'ro',
    isa => STRICT ? HashRef[ Dict[ foo => Str, bar => Int ] ] : HashRef,
);

but I think it may be cleaner to write a type like

HashRef[ Strict[ Dict[ foo => Str, bar => Int ] ] ]

The semantics of Strict is that it only validates the argument in strict mode, otherwise it is the same as Any

Compiled assertion (maybe _overload_coderef?))

I was looking for a compiled assertion to use as a callback with Getopt::Long::Descriptive and after a bit of code diving I discovered that the coderef returned by _overload_coderef seems to fit the bill. Would there be any problem with using it as such, and if not maybe an alias compiled_assertion would be a good idea?

I had to define inline_as to get my coercions working.

Beware: I am just learning Type::Tiny (together with Moo) and this is possible I completely misunderstand sth. Still...

In short: it turned out, I must define inline_as (even if I do not care) to have my checks and coercions working, without them my where and coercions were completely ignored. And finding out what is going on was very hard (quote-inlined code in debugger, tasty...).

Longer: I created some type library, mostly following manual, but making rather trivial types. For example

 declare BankAccountNo,
      as Str,
      where { 
          $_ =~ /^\d{26}$/                 
          or $_ =~ /^[A-Z]{2}\d{18,26}$/   
          or $_ = ~/^\d{8}-\d+(-\d+)+$/
          ;
      },
      message { "Bad account: $_"};

I also made coercion responsible for dropping spaces

coerce BankAccountNo,
      from Str, via {
          say "Coercing account $_";
          $_ =~ s{\s+}{}g;
          $_;
      },

and I tried using it in some Moo class:

has 'base_acc' => (is=>'ro', required=>1,
                               isa=>BankAccountNo, coerce=>BankAccountNo->coercion);

To my amazement, when I gave my class string like "10 2030 4050 1111 2222 3333 4444" as base_acc, it landed unmodified as attribute value.

After diagnosing things for some time I found, that Moo part is working (if I give some other routine as coerce, it is called), but:
a) my „where” is not called at all, instead some inherited inlined version is called
and
b) if this succeeds, coercion is not called.

Once I added inline_as (which replicated the same check as made in where), things started to work (my inline_as failed so coercion was fired)

"Default" type constraint for using with Dict and Tuple

Hi.

Maybe it will be useful to add "Default" constraint.

Dict [
    aaa => Default [Num, 10],
    bbb => Default [20],
]

It should check if key exists, and if exists - validate value type, if type constraint present.
If key not exists - create key with default value.

And the same for Tuple.

Types::Common::String reporting deeper problems

Migrated from rt.cpan.org #131756 (status was 'open')

Requestors:

From [email protected] on 2020-02-12 10:08:34
:

If I have a NonEmptyStr constraint violation , it always reports it with "Must not be empty ...". This happens for undef, references or an empty string.

With a constraint like Str, it would report on different levels:

  • Undef did not pass constraint "Str"
  • Reference ... did not pass constraint "Str"

I would had expected same kind of behaviour, reporting the deeper level violations instead of only the top level

use of overload method

A cpangrep shows that Type::Tiny::_HalfOp appears to have the same issue with using the coderef returned by overload::Method that I found in Test::More.

To correctly invoke XS methods I think you will need something like:

-	$complete_type->$method( $self->{type} );
+	$complete_type->$method( $self->{type}, undef, undef );

See also Perl/perl5#19388 for the proposed doc patch.

I didn't try to analyse what you're doing at line 788 of Types::Standard, that may also need addressing.

Please add validation_options supporting on_fail callback

Trying to migrate from Params::Validate towards Type::Params our team detected an issue regarding the logging.
In the past having in a module using Params::Validate the following snippet making use of the function validation_options

use Log::Any         qw($logger);
use Params::Validate qw(:types validation_options validate_pos);
...
validation_options(
  on_fail => sub {
    local *__ANON__ = (caller(1))[3];
    die($logger->fatal($_[0]));
  }
);

we have been able to easily log each error message raised during the validation and then to propagate the corresponding exception.
Reading the documentation of Type::Params we have not found any adequate replacement for this very useful functionality.
And, of course, we would not like to additionally catch exceptions from functions / methods using Type::Params wherever they are called - both because this would significantly increase the effort and due to annoying and dangerous redundancy caused by such approach.

As far as I see, all validation exceptions are thrown by Error::TypeTiny, which, in turn, is used by Type::Params so that the question is, whether the throw method in this module could be expanded by an additional (optional?) named parameter e.g. redirection? If omitted, throw works as before, if contains a coderef - which can be set by calling of validation_options, then throw calls at the end this function instead of the currently used die.

Thanks and Regards,
jsf

InstanceOf["Foo"] cannot be dereferenced

$ perl -MPath::Tiny -MTypes::Standard=InstanceOf -wle'InstanceOf["Path::Tiny"]->where(q{not $_->is_dir})'

Can't call method "where" on unblessed reference at -e line 1.

local $@ may be needed

#!/usr/local/bin/perl

use lib "lib";
use strict;
use Type::Tiny;

my $Type1 = Type::Tiny->new( name => "Type1", constraint => sub { 0 } );

eval { $Type1->('val1') };
warn ref $@;
warn $@;
warn $@; # <- undef!!!

__END__

% perl bug.pl 
Error::TypeTiny::Assertion at bug.pl line 10.
Value "val1" did not pass type constraint "Type1" at bug.pl line 9
    Value "val1" did not pass type constraint "Type1"
    "Type1" is defined as: sub { 0; }
Warning: something's wrong at bug.pl line 12.

How to fix it.

% git diff
diff --git a/lib/Type/Tiny.pm b/lib/Type/Tiny.pm
index 757ef64b..74b81ea0 100644
--- a/lib/Type/Tiny.pm
+++ b/lib/Type/Tiny.pm
@@ -813,6 +813,7 @@ sub _perlcode {
        return $self->inline_check( '$_' )
                if $self->can_be_inlined;
                
+        local $@;
        $b ||= do {
                require B::Deparse;
                my $tmp = "B::Deparse"->new;

Source of the problem.

require B::Deparse;

Thanks,

Inline coerce warnings: `Found = in conditional, should be ==`

I'm using inlined coercions in Mandel.

Using Perl 5.18.2 on Ubuntu 14.04, it causes warnings while coercing type Dict.

Found = in conditional, should be ==

This test show the warning:

use strict;
use warnings;
use Types::Standard -all;
my $value = { key => 'value' };
my $type = Dict[key => Str];

eval $type->coercion->inline_coercion('$value');

I've print out the inlined code, seems the warning caused here:

($new{"key"}=$tmp) : ($return_orig=1 and last DICTLABEL1)

Till now, I have to disable warnings when eval the inlined code. Would you fix it?

use %Carp::Internal in Error::TypeTiny

Hi,

we added some of our modules into %Carp::Internal to get better stacktraces, but Type::Tiny simple ignore this entries by using an own CarpInternal.

Why is there an own %CarpInternal in the first place?
Why not use directly %Carp::Internal or at least copy the content initially?

Globally deactivate validation

As mentioned in the previous issue opened by me, our team tries to migrate from Params::Validate to Type::Params.
For performance reasons a global deactivation of validation would be very useful: during the development and test phases the validation is on, but once an application is in production, the validation can usually be deactivated because in the most cases the arguments applied to the functions / methods in this application can be considered staying valid.
The performance gain is especially significant in case of daemons written in Perl.

Params::Validate uses for this purpose the environment variable PERL_NO_VALIDATION.
We would like to have something similar deactivating both the compilation and the subsequent validation provided by Type::Params.

Thanks and Regards,
jsf

Possible typo in Type::Tiny::Manual::UsingWithMoo

In the $PositiveInt declaration's inline_as block in the synopsis

inline_as { "$_ =~ /^[0-9]\$/ and $_ > 0" };

Shouldn't the \ be a + or else there is a + missing before it, to allow integers > 9 ?

Code compilation error with localized $"

Just FYI I came across a weird bug today — due to my own stupidity more than anything else, but anyways.

I happened to call a function which uses Type::Params::compile for the first time in a scope where I had said local $" = q{, }; just above because I wanted to print out some arrays as comma separated lists and couldn't be a**ed to do a join inbetween. What happened was that compilation of the check function failed because the code suddenly was sprinkled with commas! Lesson learned, but you may want to make sure that $" is set to its default value when generating the code. If I was stupid enough to do this then someone else might too. It took me nearly an hour to figure out what was going on...

Valid coercions reported as invalid if unrelated data fails

I'm assuming I'm doing something horribly wrong, but here's a tiny type library (I've tried to pare it down to a minimal test case). Note that the YAMLBool type coerces true and false to 1 and 0, respectively:

package MyTypes {
    use Type::Library -base, -declare => qw(
      YAMLBool
    );
    use Type::Params 'compile';
    use Type::Utils -all;
    use Types::Standard qw(Bool Enum Dict Optional HashRef);

    our @EXPORT_OK = 'compile';

    BEGIN {
        extends qw(
          Types::Standard
          Types::Common::Numeric
          Types::Common::String
        );
    }
    declare '_TrueFalse', as Enum [qw/true false/];
    declare 'YAMLBool',   as Bool;
    coerce 'YAMLBool',
      from '_TrueFalse', via { 'true' eq $_ ? 1 : 0 };
}

1;

And here's a program that succeeds:

use 5.26.0;
use warnings;
use lib '.';
use MyTypes qw/Dict YAMLBool Optional HashRef compile/;

my $check = compile(
    Dict [
        maybe_true    => YAMLBool,
        not_a_hashref => Optional [HashRef],
    ]
);

my $minimal = {
    maybe_true    => 'true',
    not_a_hashref => {},
};

$check->($minimal);

But as soon as I change the not_a_hashref value to a string, I get the following error:

Reference {"maybe_true" => "true","not_a_hashref" => "asdf"} did not pass type constraint "Dict[maybe_true=>YAMLBool,not_a_hashref=>Optional[HashRef]]" (in $_[0]) at fail.pl line 18
    Reference {"maybe_true" => "true","not_a_hashref" => "asdf"} did not pass type constraint "Dict[maybe_true=>YAMLBool,not_a_hashref=>Optional[HashRef]]" (in $_[0])
    "Dict[maybe_true=>YAMLBool,not_a_hashref=>Optional[HashRef]]" constrains value at key "maybe_true" of hash with "YAMLBool"
    "YAMLBool" is a subtype of "Bool"
    Value "true" did not pass type constraint "Bool" (in $_[0]->{"maybe_true"})
    "Bool" is defined as: (!ref $_ and (!defined $_ or $_ eq q() or $_ eq '0' or $_ eq '1'))

So we see the coercion is valid. However, as soon as I change something other than the coerced value to an invalid state, the coercion doesn't happen and this otherwise valid value is reported as being the source of the problem. The actual type I compiled was about 40 lines long, so this was rather hard to chase down.

  • Types::Standard version 1.012001
  • Perl 5.26.2

I've also had this happen on Linux boxes with newer Perls and older versions of Types::Standard (1.010006), so it appears that I can reliably produce it.

use Types::Common;

Types::Common should export:

  • all of Types::Standard's types
  • all of Types::Common::Numeric
  • all of Types::Common::String
  • the new API of Type::Params

POD typo: closet_match -> closest_match

POD section Methods describes oddly named method closet_match which seemingly has no corresponding code.
Conversely, code method closest_match seems undocumented in POD...

Types::Standard::StrMatch throws the avoiding callbacks warning

Migrated from rt.cpan.org #133887 (status was 'new')

Requestors:

From [email protected] on 2020-12-10 04:36:18
:

This code
use Types::Standard -types; use strict; use warnings; use Type::Utils -all;
#use re 'debug'; local $Type::Tiny::AvoidCallbacks = 0; my $Distance = declare
"Distance" => as StrMatch[ qr{^([0-9]+)\s*(mm|cm|m|km)$} ]; my $x = "5ym"; my
$y = $Distance->($x);
throws (and warns) the following:
Cannot serialize regexp without callbacks; serializing using callbacks at
/home/perl/perl5/perlbrew/perls/perl-5.8.9/lib/site_perl/5.8.9/Type/Tiny.pm
line 853 Value "5ym" did not pass type constraint "Distance" at ./test-1.pl
line 13 "Distance" is a subtype of
"StrMatch[(?-xism:^([0-9]+)\s*(mm|cm|m|km)$)]" Value "5ym" did not pass type
constraint "StrMatch[(?-xism:^([0-9]+)\s*(mm|cm|m|km)$)]"
"StrMatch[(?-xism:^([0-9]+)\s*(mm|cm|m|km)$)]" is defined as: do { package
Type::Tiny; !ref($) and $ =~
$Types::Standard::StrMatch::expressions{"Regexp|(?-xism:^([0-9]+)\s*(mm|cm|m|km)$)"}
}
on Perl 5.8.9 and 5.30.2 with or without Type::Tiny::XS installed, with or
without AvoidCallbacks set

version 1.016002 breaks Catalyst-Runtime

The changes to slurpy in 1.016002 have broken Catalyst-Runtime's handling of type constrained dispatch when using a slurpy option. Catalyst was abusing the format of the slurpy option internals to decide how many arguments should be consumed.

I have created a fix for this (perl-catalyst/catalyst-runtime@c2af9db) which I should be releasing soon. The new code feels a bit more robust, although looking at the original parameters of a type feels a bit ugly.

I'm not sure if there's really anything for Type::Tiny to do here. I figured you would like to be aware as Catalyst is a higher profile module.

Please add ->check_coerce method which returns undef if coercion fails

Migrated from rt.cpan.org #133814 (status was 'open')

Requestors:

From [email protected] on 2020-11-26 17:10:22
:

The subject pretty much says it all. There is ->coerce which returns the
original value if coercion fails, and ->assert_coerce which dies if
coercion fails but no middle ground which returns false if coercion fails.

It is true that it would just be sugar for Type->check(
Type->coerce($value) ) but it would be very useful sugar, because frankly
those nested calls are ugly, especially when it's inside an if test which
is commonly the case, and even more so in case you use a coercion object:
Coercion->type_constraint(Coercion->coerce($value))! I'm tempted to use try
{ Foo->assert_coerce($value) } but that is really even more ugly, although
less to type.

I can try to make a pull request if it would be welcome.

support for ( @args, \%options )

Howdy,

This may be pie-in-the-sky, but here goes...

There's a common subroutine signature idiom that looks like

( $arg1, $arg2, ..., $argn, \%opts )

where the trailing hashref is optional and the number of preceding arguments is variable. It's typically handled like

my $opts = 'HASH' eq ref $_[-1] ? pop : {};
my @args = @_;

Or with Type::Tiny, maybe something a little unwieldy like this,

my ( $args, $opts ) = validate (
                                [ \@_,
                                  'HASH' eq ref $_[-1] ? pop : (),
                                ],
                                ArrayRef,
                                Optional[ Dict[ foo => Any ] ],
                               );

Instead, something like this would be so much nicer:

my ( $args, $opts ) = validate( \@_, slurpyish ArrayRef, Optional[ Dict[ foo => Any ] );

where when the type parser sees slurpyish it skips to the end and works backwards. (I can imagine a universe where if one always scanned backwards, plain old slurpy could be used, but I haven't examined all of the corner cases in that universe to know if it really exists.)

Just a thought...

Thanks,
Diab

Trouble using user-defined class

This is more a question, but can't figure this out from the documentation. I'm trying to use Moo with Type::Tiny. I have a User class (package Models::User) and a Course class (Models::Course). The course will have an ArrayRef of users using:

package Models::Course;

use Models::User;

use Types::Standard qw/ArrayRef/;

use Moo;

has 'users' => (
    is => 'rw',
    isa => ArrayRef['Models::User']
);

but when running this, I get the error:

Parameter to ArrayRef[`a] expected to be a type constraint; got Models::User at /Volumes/WW_test/opt/local/lib/perl5/site_perl/5.12.3/Types/Standard/ArrayRef.pm line 24.
Compilation failed in require at testModels.pl line 1.
BEGIN failed--compilation aborted at testModels.pl line 1.

and seems to be failing at the 'users' attribute.

I think this is because I may not have my Models::User defined correctly. It appears looking through the code that it needs an @isa defined, but since it doesn't have a super class, I have the following at the top:

package Models::User;

use Moo;

use base qw(Exporter);
#our @EXPORT_OK = qw(User);
our @ISA = "";

Should there be some class for the @isa variable?

Im looking for a way to encapsulate defaults with Type::Tiny types.

I would like to do something like the following:

use strict;
use warnings;

package Types::Theme;

use strict;
use warnings;

use Types::Standard  qw(Str);
use Type::Tiny       ();

use Type::Library -base;

sub get_default_theme {
    # lets assume this is way more complex...
    return 'default';
}

__PACKAGE__->add_type(
    Type::Tiny->new(
        name       => 'Theme',
        parent     => Str,
        default => sub { get_default_theme() },
    )
);

1;

package Test::Object;
use Mouse;
use Types::Theme -mouse, qw(Theme);

has theme => ( is => 'rw', isa => Theme );

1;

package main;

use Test::Object;

my $obj = Test::Object->new();
say $obj->theme; # should return  `default`
$obj->theme("custom");
say $obj->theme; # should return `custom`

I know Moose, Mouse and Moo provide a default mechnism like:

package Test::Object;
use Mouse;
use Types::Theme -mouse, qw(Theme);

has theme => ( is => 'rw', isa => Theme, default => sub { ... );

1;

But this means that every place I defined a theme in my object model I need to also add the common default. If there was a way to bundle the default with the Type::Tiny, that would be amazing.

I wondered if I just missed such a mechanism in the current Type::Tiny or if this was a new idea that had merit to add to the library?

Please advise and thanks for an awesome tool

Can't locate object method "history" via package "Test::Builder"

$ cpanm Type::Tiny
...
t/30-integration/Moose/accept-moose-types.t ............... ok
Name "Moose::Meta::TypeCoercion::dummy_3" used only once: possible typo at t/30-integration/Moose/basic.t line 308.
Name "Moose::Meta::TypeConstraint::dummy_1" used only once: possible typo at t/30-integration/Moose/basic.t line 305.
t/30-integration/Moose/basic.t ............................ ok
t/30-integration/Moose/coercion.t ......................... skipped: Moose version 2.12 required--this is only version 2.1005 at (eval 6) line 1.
t/30-integration/Moose/inflate-then-inline.t .............. ok
Can't locate object method "history" via package "Test::Builder" at /usr/lib/perl5/Test/Moose.pm line 80.
# Tests were run but no plan was declared and done_testing() was not seen.
# Looks like your test exited with 255 just after 1.
t/30-integration/Moose/native-attribute-traits.t ..........
Dubious, test returned 255 (wstat 65280, 0xff00)
All 1 subtests passed
t/30-integration/MooseX-Getopt/coercion.t ................. skipped: MooseX::Getopt version 0.63 required--this is only version 0.59 at (eval 238) line 1.
...
Test Summary Report
...
t/30-integration/Moose/native-attribute-traits.t (Wstat: 65280 Tests: 1 Failed: 0)
Non-zero exit status: 255
Parse errors: No plan found in TAP output
Files=151, Tests=1834, 26 wallclock secs ( 0.57 usr 0.24 sys + 20.20 cusr 3.64 csys = 24.65 CPU)
Result: FAIL
Failed 1/151 test programs. 0/1834 subtests failed.
make: *** [test_dynamic] Error 255

$ cat /etc/issue
Ubuntu 14.04.5 LTS

$ perl -v
This is perl 5, version 18, subversion 2 (v5.18.2) built for x86_64-linux-gnu-thread-multi

FileHandle behaviour is different between Type::Tiny and Type::Tiny::XS

$ perl -MIO::String -MTypes::Standard=:types -E 'FileHandle->assert_valid( IO::String->new ) and say "OK"'
OK

$ perl -MDevel::Hide=Type::Tiny::XS -MIO::String -MTypes::Standard=:types -E 'FileHandle->assert_valid( IO::String->new ) and say "OK"'
Devel::Hide hides Type/Tiny/XS.pm
Reference bless( \*Symbol::GEN0, 'IO::String' ) did not pass type constraint "FileHandle" at -e line 1
    Reference bless( \*Symbol::GEN0, 'IO::String' ) did not pass type constraint "FileHandle"
    "FileHandle" is defined as: ((ref($_) eq "GLOB" && Scalar::Util::openhandle($_)) or (Scalar::Util::blessed($_) && $_->isa("IO::Handle")))

This is with Type::Tiny 1.000005 and Type::Tiny::XS 0.012.

StrMatch plus_coercions broken in >= 1.015_000

Hi, I hope this report is helpful. I'm unsure if I'm using plus_coercions correctly, but my code worked until I upgraded to the latest Type::Tiny.

Here's a one-file example of what's happening:

#!/usr/bin/env perl

use v5.12;

package MyBookList {

    use Readonly;

    use Moo;
    use Types::Standard qw( StrMatch InstanceOf );
    use Type::Params    qw( compile wrap_subs Invocant );

    Readonly(
        my $UUID_RE => qr{
        ^
        [0-9a-fA-F]{8}-
        [0-9a-fA-F]{4}-
        [0-9a-fA-F]{4}-
        [0-9a-fA-F]{4}-
        [0-9a-fA-F]{12}
        $
    }sxm
    );

    wrap_subs remove_book => compile( Invocant,
        StrMatch( [$UUID_RE] )
          ->plus_coercions( InstanceOf ['MyBook'], sub { shift->uuid } ) );

    sub remove_book {
        my $self = shift;
        my $uuid = shift;

        say "Attempting to remove $uuid";

        return $self;
    }

}

package MyBook {
    use Moo;

    has name => ( is => 'rw' );
    has uuid => ( is => 'rw' );
}

use MyBook;

my $book1 = MyBook->new(
    title => 'Doon',
    uuid  => '12345678-9999-9999-9999-123456789012'
);

my $m = MyBookList->new();
$m->remove_book('12345678-1234-1234-1234-123456789012');    # Remove by UUID
$m->remove_book($book1);    # Remove by MyBook object

with Tiny::Type version 1.014000 the code parses cleanly and runs correctly,

$ perl -MType::Tiny -e 'print $Type::Tiny::VERSION ."\n";'
1.014000
$ ./onefile.pl
Attempting to remove 12345678-1234-1234-1234-123456789012
Attempting to remove 12345678-9999-9999-9999-123456789012

but starting from 1.015_000 I get variations of this

$ perl -MType::Tiny -e 'print $Type::Tiny::VERSION ."\n";'
1.016008
$ ./onefile.pl 
Bareword found where operator expected at parameter validation for __ANON__::__ANON__ line 14, near "9a"
	(Missing operator before a?)
Bareword found where operator expected at parameter validation for __ANON__::__ANON__ line 15, near "9a"
	(Missing operator before a?)
Bareword found where operator expected at parameter validation for __ANON__::__ANON__ line 16, near "9a"
	(Missing operator before a?)
Bareword found where operator expected at parameter validation for __ANON__::__ANON__ line 17, near "9a"
	(Missing operator before a?)
Bareword found where operator expected at parameter validation for __ANON__::__ANON__ line 18, near "9a"
	(Missing operator before a?)
Scalar found where operator expected at parameter validation for __ANON__::__ANON__ line 20, near "}
	        $
	    )"
	(Missing operator before 	    )?)
Scalar found where operator expected at parameter validation for __ANON__::__ANON__ line 21, near ")
	$tmp"
	(Missing operator before $tmp?)
Failed to compile source because: syntax error at parameter validation for __ANON__::__ANON__ line 13, near ";

	# Parameter $_[1] (type: StrMatch[(?^umsx:
	        ^"
syntax error at parameter validation for __ANON__::__ANON__ line 15, near "9a"
syntax error at parameter validation for __ANON__::__ANON__ line 16, near "9a"
Global symbol "$tmp" requires explicit package name (did you forget to declare "my $tmp"?) at parameter validation for __ANON__::__ANON__ line 21.
Global symbol "$coercion_for_arg_1" requires explicit package name (did you forget to declare "my $coercion_for_arg_1"?) at parameter validation for __ANON__::__ANON__ line 21.
Global symbol "$tmp" requires explicit package name (did you forget to declare "my $tmp"?) at parameter validation for __ANON__::__ANON__ line 22.
Global symbol "$tmp" requires explicit package name (did you forget to declare "my $tmp"?) at parameter validation for __ANON__::__ANON__ line 22.
Global symbol "$tmp" requires explicit package name (did you forget to declare "my $tmp"?) at parameter validation for __ANON__::__ANON__ line 23.
Global symbol "@out" requires explicit package name (did you forget to declare "my @out"?) at parameter validation for __ANON__::__ANON__ line 24.
Global symbol "$tmp" requires explicit package name (did you forget to declare "my $tmp"?) at parameter validation for __ANON__::__ANON__ line 24.
Global symbol "@out" requires explicit package name (did you forget to declare "my @out"?) at parameter validation for __ANON__::__ANON__ line 26.
syntax error at parameter validation for __ANON__::__ANON__ line 27, near ";
}"
parameter validation for __ANON__::__ANON__ has too many errors. at /home/sbg/perl5/perlbrew/perls/TypeTinyTest/lib/site_perl/5.36.0/Eval/TypeTiny/CodeAccumulator.pm line 113.

I can work around it. For now, I'm locking my container to 1.014000.

Weird error messages

Is this what the error messages are supposed to look like? They seem a bit repetitive.

Value "hi" did not pass type constraint "Num" (in $args->{"region"}) at (eval 81) line 56
    "Num" is a subtype of "LaxNum"
    Value "hi" did not pass type constraint "LaxNum" (in $args->{"region"})
    "LaxNum" is defined as: (defined($_) && !ref($_) && Scalar::Util::looks_like_number($_))

Here is the code I used to generate this message:

#!/usr/bin/env perl
use feature qw/say/;

package Boop;
use Moo;
use Types::Standard qw/:all/;
has region => (isa => Num, is => 'ro');

my $a = Boop->new(region => 'hi');
say $a->region;

Incorrect code example in Type::Utils

Howdy.

Type::Utils provides the following example for inline_as:

declare EvenInt,
   as Int,
   where { $_ % 2 == 0 },
   inline_as {
      return (undef, "($_ % 2 == 0)");
   };

There are a couple of problems;

  1. The code that is returned is in double quotes, which prematurely interpolates $_
  2. It seems that the value is actually available as $_[0], not $_

To wit running

use 5.10.0;
use Type::Utils -all;
use Types::Standard -types;
use Type::Library -base, -declare => qw( GoodEvenInt BadEvenInt  );

declare BadEvenInt,
    as Int,
    where { $_ % 2 == 0 },
    inline_as {
       return (undef, '($_ % 2 == 0)')
    }
    ;

declare GoodEvenInt,
    as Int,
    where { $_ % 2 == 0 },
    inline_as {
       return (undef, '($_[0] % 2 == 0)')
    }
    ;

say 'Bad';
say "2: ", BadEvenInt->validate( 2 );
say "3: ", BadEvenInt->validate( 3 );

say 'Good';
say "2: ", GoodEvenInt->validate( 2 );
say "3: ", GoodEvenInt->validate( 3 );

produces

Bad
2:
3:
Good
2:
3: Value "3" did not pass type constraint "GoodEvenInt"

Possible missing sentences bits in Type::Tiny::Manual::Optimization

Hi Toby,

I keep reading your documentation and found some suspicious content in the Types that can be accelerated sections of Type::Tiny::Manual::Optimization POD: it looks like some sentences bits are missing.

I guess they are "something", where something would be the missing part? I searched older versions of Type::Tiny for something that could have been removed accidentally but couldn't find any more information.

Not 100% sure of what I am reporting here, but I tend to think something is missing: in the case I am wrong, please forgive me and ignore this, then I'll go get some English lesson.

Useless source code locations in error messages when type checks fail

I've noticed that the file names and line numbers given in the error messages when Type::Tiny's type checks fail do not really make sense. Please consider the following minimal and standalone example:

# a.pl

package Foo;

use Moo;
use Types::Standard qw( Int );

has 'name' =>
    is => 'ro',
    isa => Int,
    required => 1;

package main;

Foo->new(name => 'a');

Then running perl a.pl gives

Value "a" did not pass type constraint "Int" (in $args->{"name"}) at (eval 60) line 62
    "Int" is a subtype of "Num"
    "Num" is a subtype of "LaxNum"
    Value "a" did not pass type constraint "LaxNum" (in $args->{"name"})
    "LaxNum" is defined as: (defined($_) && !ref($_) && Scalar::Util::looks_like_number($_))

Please note the source code location for the culprit, (eval 60) line 62 which does not really make sense. The actual guilty line, Foo->new(name => 'a');, is actually at file a.pl, line 15.

Using Moose with its builtin type system in the a.pl file above, as follows,

# b.pl

package Foo;

use Moose;

has 'name' =>
    is => 'ro',
    isa => 'Int',
    required => 1;

package main;

Foo->new(name => 'a');

does give the meaningful guilty line location:

$ perl b.pl
Attribute (name) does not pass the type constraint because: Validation failed for 'Int' with value "a" at /usr/local/Cellar/perl/5.20.1/lib/site_perl/5.20.1/darwin-thread-multi-2level/Moose/Object.pm line 24
    Moose::Object::new('Foo', 'name', 'a') called at b.pl line 14

Please note the text "at b.pl line 14" in the output above, which is the exact location for the culprit.

I'm using the latest CPAN version of Type::Tiny and Moo:

$ sudo cpan Type::Tiny Moo
...
Type::Tiny is up to date (1.000005).
Moo is up to date (2.000001).

And I've tried both perl 5.20.1 and perl 5.16.2 on my Mac OS X 10.9.5 system and got exactly the same results.

Any help here will be highly appreciated because I really want to migrate from Moose to Moo + Type::Tiny. Thank you in advance!

Bundled types error messages

Hello! I'm using Type::Tiny to write a library that validates input data. So far, it's working very well.

I'm a bit puzzled why Types::Standard does not have detailed error messages specified. They seem to report an error in format that looks more or less like value "value" did not pass the type constraint "Type". Types::Common::Numeric and Types::Common::String have their error messages declared nicely, like Must be a positive integer for PositiveInt.

I never expected Type::Tiny error messages to be suitable for end users of my library to see, and I created a mechanism that allows for overriding the error messages, but it would be nice for them to at least have the same format across the type libraries shipped with Type::Tiny. Unless someone wants to internationalize the messages, the error message of PositiveInt or other Types::Common::* types is perfectly fine, but other types bundled in the distribution are a bit surprising with their error format.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.