Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible to use class name as a type name? #36

Closed
mschout opened this issue Nov 2, 2018 · 6 comments
Closed

Possible to use class name as a type name? #36

mschout opened this issue Nov 2, 2018 · 6 comments

Comments

@mschout
Copy link

mschout commented Nov 2, 2018

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) { ... }
@tobyink
Copy link

tobyink commented Nov 2, 2018

Does this work?

method foo2((InstanceOf['URI']) $uri) { ... }

@mschout
Copy link
Author

mschout commented Nov 3, 2018

It does. Thank you!

@vanHoesel
Copy link

@tobyink ... can you please explain why method foo( InstanceOf['URI'] $uri) { ... } is not working?

@tobyink
Copy link

tobyink commented Feb 18, 2019

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.

@mauke
Copy link
Owner

mauke commented Mar 31, 2023

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.

@mauke mauke closed this as completed Mar 31, 2023
@tobyink
Copy link

tobyink commented Mar 31, 2023

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";
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants