Skip Menu |
 

This queue is for tickets about the Type-Tiny CPAN distribution.

Report information
The Basics
Id: 132918
Status: open
Priority: 0/
Queue: Type-Tiny

People
Owner: Nobody in particular
Requestors: kaw [...] heise.de
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: Unable to use provided is_InstanceOf
Date: Wed, 1 Jul 2020 09:11:04 +0200
To: bug-Type-Tiny [...] rt.cpan.org
From: Kai Wasserbäch <kaw [...] heise.de>
Download (untitled) / with headers
text/plain 639b
I'm trying to use is_InstanceOf, but so far have found no way to pass in the object and the name. Calling my $obj = MyObject->new; if(is_InstanceOf($obj, 'MyObject)) {…} always yields true and executes the guarded path. Looking at the code it is not clear to me how I am supposed to hand in the variable to check as well as the allowed values. The solution to this bug can be: 1. Document how to call is_InstanceOf and other checks, that allow passing in the definition of valid values. (And if required: implement a way to do this) 2. Don't export is_* methods for checks that require additional values, if they can't be passed in.
is_InstanceOf($x) is the same as InstanceOf->check($x) which is basically the same as blessed($x).
Subject: Re: [rt.cpan.org #132918] Unable to use provided is_InstanceOf
Date: Mon, 13 Jul 2020 07:03:01 +0200
To: bug-Type-Tiny [...] rt.cpan.org
From: Kai Wasserbäch <kaw [...] heise.de>
Download (untitled) / with headers
text/plain 552b
On 12/07/2020 01:46, Toby Inkster via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=132918 > > > is_InstanceOf($x) is the same as InstanceOf->check($x) which is basically the same as blessed($x).
Ok, that would sort of solve is_InstanceOf() but not the other checks with additional parameters, right? Or how would one use is_Enum(), for example? In any case the usage of is_InstanceOf() should at least be documented. My preferred solution would still be, that one could write is_InstanceOf($foo, 'MyObject') and get true/false back.
Download (untitled) / with headers
text/plain 787b
It does certainly make sense. Also, say: is_ArrayRef( \@integers, Int ) However, the is_Foo functions have a ($) prototype, so allowing them to take a second parameter could break backcompat in some cases. As a side-note, you can do this: use Types::Standard is_InstanceOf => { of => 'Foo', -as => 'is_Foo', }; my $obj = bless {}, "Foo"; if ( is_Foo $obj ) { print "Found a foo!\n"; } Assuming you have Type::Tiny::XS installed, the is_Foo() function will be implemented in XS so REALLY fast. Faster than checking: if ( blessed($obj) && $obj->isa("Foo") ) { print "Found a foo!\n"; } Similar speed (I need to benchmark it more) to the new Perl 5.32 isa operator: if ( $obj isa Foo ) { print "Found a foo!\n"; }
Subject: Re: [rt.cpan.org #132918] Unable to use provided is_InstanceOf
Date: Fri, 17 Jul 2020 12:41:32 +0200
To: bug-Type-Tiny [...] rt.cpan.org
From: Kai Wasserbäch <kaw [...] heise.de>
Download (untitled) / with headers
text/plain 1.3k
Toby Inkster via RT wrote on 17.07.20 12:21: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=132918 > > > It does certainly make sense. Also, say: > > is_ArrayRef( \@integers, Int ) > > However, the is_Foo functions have a ($) prototype, so allowing them to take a second parameter could break backcompat in some cases.
Would the backward compatibility be maintained if you allowed such a second parameter only for tests like is_Enum, which don't make any sense without the second parameter? is_ArrayRef(\@params, Int) would be nice too, but I can very well cope with is_ArrayRef(\@params) && all {is_Int($_)} @params) as a construct. Show quoted text
> As a side-note, you can do this: > > use Types::Standard is_InstanceOf => { > of => 'Foo', > -as => 'is_Foo', > }; > > my $obj = bless {}, "Foo"; > > if ( is_Foo $obj ) { > print "Found a foo!\n"; > } > > Assuming you have Type::Tiny::XS installed, the is_Foo() function will be implemented in XS so REALLY fast. Faster than checking: > > if ( blessed($obj) && $obj->isa("Foo") ) { > print "Found a foo!\n"; > } > > Similar speed (I need to benchmark it more) to the new Perl 5.32 isa operator: > > if ( $obj isa Foo ) { > print "Found a foo!\n"; > }
Thanks, I'll look into this. The isa operator is not yet available to me reliably, but the rest should be possible.
Download (untitled) / with headers
text/plain 750b
Show quoted text
> is_ArrayRef(\@params) && all {is_Int($_)} @params)
If @params has more than, say, 10 integers, then you'll probably find this to be faster: ArrayRef->of(Int)->check( \@params ) I've also been working lately on something like: Int->all( @params ) # => bool Int->any( @params ) # => bool my @ints = Int->grep( @params ) # => list of ints And: my $Rounded = Int->plus_coercions(Num, 'int($_)'); my @ints = $Rounded->map( @numbers ); I will think about adding is_InstanceOf($obj, $class) but more likely I'll just document that for some parameterized types, the is_* functions aren't very useful. is_InstanceOf = is_Object is_HasMethods = is_Object is_Enum = is_Str is_StrMatch = is_Str and so on.
Download (untitled) / with headers
text/plain 368b
I've now released isa.pm which is separate from Type::Tiny (but will hook into Type::Tiny::XS if it's available) that lets you do this: use isa 'MyObject'; my $obj = MyObject->new; if ( isa_MyObject $obj ) { ...; } It is way faster than a two-argument form of is_InstanceOf could ever be, and even twice the speed of the Perl 5.32 native isa operator.
Subject: Re: [rt.cpan.org #132918] Unable to use provided is_InstanceOf
Date: Mon, 7 Sep 2020 06:58:57 +0200
To: bug-Type-Tiny [...] rt.cpan.org
From: Kai Wasserbäch <kaw [...] heise.de>
Download (untitled) / with headers
text/plain 785b
On 04/09/2020 22:31, Toby Inkster via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=132918 > > > I've now released isa.pm which is separate from Type::Tiny (but will hook into Type::Tiny::XS if it's available) that lets you do this: > > use isa 'MyObject'; > > my $obj = MyObject->new; > if ( isa_MyObject $obj ) { > ...; > } > > It is way faster than a two-argument form of is_InstanceOf could ever be, and even twice the speed of the Perl 5.32 native isa operator.
Thank you very much, that looks very promising! With regards to a construct like ArrayRef->of(Int)->check( \@params ) from your previous E-Mail: yeah, that is a good advice and I would expect the is_* methods to map to that, if they are possible. In any case: thanks a lot!
Download (untitled) / with headers
text/plain 1.3k
I was pretty convinced that the is_ functions were prototyped ($) so allowing them to accept a second argument would break stuff. Turns out that the is_ functions don't have prototypes, so it shouldn't break anything that assumed a prototype of ($). It's very easy to implement. (About 4 new lines of code, and a change to one existing line.) However, it has one big drawback. Currently checks like is_ArrayRef, is_HashRef, etc can be done using an XS sub. To allow is_ArrayRef($foo, Int) to work, they'd need to be wrapped in a Perl sub, making them much slower. Before the change, is_Object(undef) and is_InstanceOf(undef) run at the same speed: [tai@titania pts/5 p5-type-tiny]$ perl bench.tmp Rate is_Object is_InstanceOf is_Object 24439618/s -- -2% is_InstanceOf 24922676/s 2% -- After the change, is_InstanceOf(undef) gets slowed right down! [tai@titania pts/5 p5-type-tiny]$ perl -Ilib bench.tmp Rate is_InstanceOf is_Object is_InstanceOf 4633858/s -- -81% is_Object 24439618/s 427% -- Slowing down is_InstanceOf isn't a huge issue really, because people still have a fast is_Object. But slowing down is_ArrayRef and is_HashRef are a big no from me.
Download (untitled) / with headers
text/plain 298b
I did also have the idea of making it opt-in, like: use Types::Standard -autoparam, qw( is_InstanceOf ); But then if you see `is_InstanceOf` in code, you need to scroll up to find the `use` statement to figure out which version of the function you're dealing with, and I don't like that idea.
Download (untitled) / with headers
text/plain 657b
Perhaps having a general "is()" function would be useful? use strict; use warnings; use feature 'say'; { my %cache; sub is { my $type = shift; my $caller = caller; my $check = ( $cache{$caller}{$type} ||= do { require Type::Utils; my $type_object = Type::Utils::dwim_type($type, for => $caller); if ( ! $type_object ) { require Carp; Carp::confess("Cannot find type $type; failed"); return !!0; } $type_object->compiled_check; } ); goto $check if @_==1; $check->($_) || return !!0 for @_; return !!1; } } say is( 'ArrayRef' => [] ); say is( 'InstanceOf[Bleh]' => bless({}, 'Bleh') );
Subject: Re: [rt.cpan.org #132918] Unable to use provided is_InstanceOf
Date: Tue, 8 Sep 2020 07:03:21 +0200
To: bug-Type-Tiny [...] rt.cpan.org
From: Kai Wasserbäch <kaw [...] heise.de>
Subject: Re: [rt.cpan.org #132918] Unable to use provided is_InstanceOf
To: bug-Type-Tiny [...] rt.cpan.org
From: Kai Wasserbäch <kaw [...] heise.de>
Download (untitled) / with headers
text/plain 1.2k
On 07/09/2020 14:22, Toby Inkster via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=132918 > > > Perhaps having a general "is()" function would be useful? > > use strict; > use warnings; > use feature 'say'; > > { > my %cache; > sub is { > my $type = shift; > my $caller = caller; > my $check = ( $cache{$caller}{$type} ||= do { > require Type::Utils; > my $type_object = Type::Utils::dwim_type($type, for => $caller); > if ( ! $type_object ) { > require Carp; > Carp::confess("Cannot find type $type; failed"); > return !!0; > } > $type_object->compiled_check; > } ); > goto $check if @_==1; > $check->($_) || return !!0 for @_; > return !!1; > } > } > > say is( 'ArrayRef' => [] ); > say is( 'InstanceOf[Bleh]' => bless({}, 'Bleh') );
Yeah, this would be quite good too. Sure the sugar of saying is_Foo is really nice, but if that's impossible to do fast, then I would certainly vote for something like this, which is still very easy to read (though the non-functional is_* methods should still be removed/no longer be exported or at the very least documented as "don't do what you expect"). The is() method would be a wonderful addition IMHO.
Download OpenPGP_0x4142C9A807C9D0B9.asc
application/pgp-keys 7k

Message body not shown because it is not plain text.

Download OpenPGP_signature
application/pgp-signature 840b

Message body not shown because it is not plain text.



This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.