Function-Parameters
Function-Parameters copied to clipboard
Possible to use class name as a type name?
In porting over a codebase from Method::Signatures, I am dealing with a lot of methods that were using class names in the parameter lists. For example:
use Function::Parameters;
use URI;
use Types::Standard qw(ArrayRef);
method foo(URI $uri) { ... } # Undefined type name error
method foobar(ArrayRef[URI] $uris) { ... } # missing type name after '[' error
This seems to not work with Function::Parameters
, or, I have missed the way to get these working. Using Types::Standard
I tried things such as:
use Types::Standard qw(InstanceOf ArrayRef);
method foo1(InstanceOf[URI] $uri) { ... } # Undefined type name URI error
method foo2(InstanceOf['URI'] $uri) { ... } # missing type name after '[' error
method foo3(ArrayRef[ InstanceOf[URI] ] $uris) { ... } # Undefined type name URI error
method foo4(ArrayRef[ InstanceOf['URI'] ] $uris) { ... } # missing type name after '[' error
So either I am missing how to get this to work, or, I need to drop the class type constraints altogether and just use something like:
method foo1($uri) { ... }
method foo2(ArrayRef $uris) { ... }
Does this work?
method foo2((InstanceOf['URI']) $uri) { ... }
It does. Thank you!
@tobyink ... can you please explain why method foo( InstanceOf['URI'] $uri) { ... }
is not working?
Because you left out the parentheses around the type name.
method foo((InstanceOf['URI']) $uri) { ... }
See the Function::Parameters documentation for what exactly those do.
In addition to what @tobyink said, you can also define ad-hoc type constants:
use constant {
T_URI => InstanceOf['URI'],
};
method foo(T_URI $uri, ArrayOf[T_URI] $uris) { ... }
Or for maximum DWIMery, write a custom type reifier that turns undefined type names (which are normally looked up as subroutines in the current package) into InstanceOf
constraints.
If you have a recent version of Type::Tiny
installed, the following should also work:
use Function::Parameters;
use Type::Tiny::Class v2.0 qw( URI HTTP::Tiny );
method get_uri ( URI $uri, HTTPTiny $ua ) {
my $response = $ua->get( $uri );
if ( $response->{success} ) {
return $response->{content};
}
die "response failed";
}