NAME
Venus::Type - Type Class
ABSTRACT
Type Class for Perl 5
SYNOPSIS
package main;
use Venus::Type;
my $type = Venus::Type->new;
# bless({}, "Venus::Type")
DESCRIPTION
This package provides a mechanism for parsing, generating, and validating data type expressions and subroutine signatures.
Types
The following types are supported by the parser:
Simple Types
Simple types are basic types supported directly without requiring parameters or nested structures. They include:
any-
Accepts any value.
Example expression:
anyExample parsed output:
["any"] array-
Accepts array references.
Example expression:
arrayExample parsed output:
["array"] arrayref-
Accepts array references.
Example expression:
arrayrefExample parsed output:
["arrayref"] bool-
Accepts boolean values (true or false).
Example expression:
boolExample parsed output:
["bool"] boolean-
Accepts boolean values (true or false).
Example expression:
booleanExample parsed output:
["boolean"] code-
Accepts code references.
Example expression:
codeExample parsed output:
["code"] coderef-
Accepts code references.
Example expression:
coderefExample parsed output:
["coderef"] defined-
Accepts any value that is defined (not undefined).
Example expression:
definedExample parsed output:
["defined"] dirhandle-
Accepts dirhandle values.
Example expression:
dirhandleExample parsed output:
["dirhandle"] filehandle-
Accepts filehandle values.
Example expression:
filehandleExample parsed output:
["filehandle"] float-
Accepts floating-point values.
Example expression:
floatExample parsed output:
["float"] glob-
Accepts typeglob values.
Example expression:
globExample parsed output:
["glob"] hash-
Accepts hash references.
Example expression:
hashExample parsed output:
["hash"] hashref-
Accepts hash references.
Example expression:
hashrefExample parsed output:
["hashref"] identity-
Accepts objects of the specified type.
Example expression:
identity[Example]Example parsed output:
["identity", "Example"] number-
Accepts numeric values (integers and floats).
Example expression:
numberExample parsed output:
["number"] object-
Accepts package (or class) instances.
Example expression:
objectExample parsed output:
["object"] package-
Accepts package names.
Example expression:
packageExample parsed output:
["package"] reference-
Accepts any reference type.
Example expression:
referenceExample parsed output:
["reference"] regexp-
Accepts regular expression objects.
Example expression:
regexpExample parsed output:
["regexp"] scalar-
Accepts scalar references.
Example expression:
scalarExample parsed output:
["scalar"] scalarref-
Accepts scalar references.
Example expression:
scalarrefExample parsed output:
["scalarref"] string-
Accepts string values.
Example expression:
stringExample parsed output:
["string"] undef-
Accepts undefined values.
Example expression:
undefExample parsed output:
["undef"] value-
Accepts defined, non-reference, scalar values.
Example expression:
valueExample parsed output:
["value"] yesno-
Accepts a string value, case-insensitive, that is either
y,yes,1,n,no, or0.Example expression:
yesnoExample parsed output:
["yesno"]
Complex Types
Complex types are types that can take one or more type expressions as arguments or involve nesting. These include:
attributes-
Accepts objects with attributes matching the specified names and types.
Example expression:
attributes[name, string]Example parsed output:
["attributes", "name", "string"] consumes-
Accepts objects that consume the specified role.
Example expression:
consumes[Example::Role]Example parsed output:
["consumes", "Example::Role"] either-
Accepts one of the provided type expressions.
Example expression:
string | numberExample parsed output:
["either", "string", "number"] hashkeys-
Accepts hashes containing keys whose values match the specified types.
Example expression:
hashkeys[name, string]Example parsed output:
["hashkeys", "name", "string"] includes-
Accepts all of the provided type expressions.
Example expression:
string + numberExample parsed output:
["includes", "string", "number"] inherits-
Accepts objects that inherit from the specified type.
Example expression:
inherits[Example]Example parsed output:
["inherits", "Example"] integrates-
Accepts objects that support the "does" behavior and consume the specified role.
Example expression:
integrates[Example::Role]Example parsed output:
["integrates", "Example::Role"] maybe-
Accepts the provided type or an undefined value.
Example expression:
maybe[string]Example parsed output:
["maybe", "string"] routines-
Accepts an object having all of the routines specified.
Example expression:
routines[new]Example parsed output:
["routines", "new"] tuple-
Accepts array references that conform to a tuple specification.
Example expression:
tuple[string, number]Example parsed output:
["tuple", "string", "number"] within-
Accepts array references, hash references, or mappables (i.e. objects derived from classes which consume the "mappable" role, see Venus::Role::Mappable), whose values match the specified type expression.
Example expression:
within[arrayref, string]Example parsed output:
["within", "arrayref", "string"]
Type Expressions
A type expression is a combination of one or more simple or complex types, optionally with parameters, that describes a data structure or value expected by the system.
Expression Components
either - Denoted by a pipe symbol,
|, and used to accept one of multiple types. For example:string | number.includes - Denoted by a plus symbol,
+, and used to require all of the specified types. For example:string + number.string-simple - A simple string is an unquoted string matching the regular expression:
^\w+$.string-quoted - A quoted string is either single-quoted or double-quoted. For example:
'name'or"name".string-package - A string-package refers to a Perl package name, following the regular expression:
^[A-Z](?:(?:\w|::)*[a-zA-Z0-9])?$.parameterized - A parameterized type includes a type followed by an open square bracket,
[, followed by one or more type expressions separated by commas, and a closing square bracket,]. For example,within[arrayref, string]means an array reference where each element is a string.
Subroutine Signatures
A subroutine signature is a string that defines the name of a subroutine, its input types, and its output types. The parser supports subroutine signatures in the following format: name(input_type $variable, ...) (output_type).
name - The name of the subroutine.
() - Parentheses enclosing the input type expressions.
input_type - Each input is a type expression followed by a Perl variable (e.g.,
$variable)., - If more than one input exists, they are separated by a comma.
() - Parentheses enclosing the output type expression.
output_type - The type expression for the output of the subroutine.
Signature Examples
chmod(string $mode) (Venus::Path)-
A subroutine
chmodtakes a single argument: a string variable$mode, and returns aVenus::Path. copy(string | Venus::Path $path) (Venus::Path)-
A subroutine
copytakes an argument$path, which can be either a string or aVenus::Pathobject, and returns aVenus::Path. directories() (within[arrayref, Venus::Path])-
A subroutine
directoriestakes no arguments and returns a list ofVenus::Pathobjects contained in an array reference. find(string | regexp $expr) (within[arrayref, Venus::Path])-
A subroutine
findtakes a string or regular expression as input and returns a list ofVenus::Pathobjects contained in an array reference. mkdir(maybe[string] $mode) (Venus::Path)-
A subroutine
mkdiraccepts an optional string argument$mode(orundef) and returns aVenus::Pathobject. root(string $spec, string $base) (maybe[Venus::Path])-
A subroutine
rootaccepts two string arguments and may return aVenus::Pathobject orundef.
Usage Examples
- Parsing an "includes" expression
-
my $parsed = $type->expression('object + within[arrayref, either[string, number]]'); # ['includes', 'object', ['within', 'arrayref', ['either', 'string', 'number']]] - Generating an "includes" expression
-
my $generated = $type->expression(['includes', 'object', ['within', 'arrayref', ['either', 'string', 'number']]]); # object + within[arrayref, either[string, number]] - Parsing an "either" expression
-
my $parsed = $type->expression('string | number | within[arrayref, string | number]'); # ['either', 'string', 'number', ['within', 'arrayref', ['either', 'string', 'number']]] - Generating an "either" expression
-
my $generated = $type->expression(['either', 'string', 'number', ['within', 'arrayref', ['either', 'string', 'number']]]); # string | number | within[arrayref, string | number] - Parsing a subroutine signature
-
my $parsed = $type->signature('copy(string | Venus::Path $path) (Venus::Path)'); # ['copy', [['string | Venus::Path', '$path']], ['Venus::Path']] - Generating a subroutine signature
-
my $generated = $type->signature(['copy', [['string | Venus::Path', '$path']], ['Venus::Path']]); # copy(string | Venus::Path $path) (Venus::Path)
INHERITS
This package inherits behaviors from:
INTEGRATES
This package integrates behaviors from:
METHODS
This package provides the following methods:
assert
assert(string $expr) (Venus::Assert)
Returns a Venus::Assert object based on the type expression provided.
Since 4.15
- assert example 1
-
# given: synopsis; my $assert = $type->assert('string | number'); # bless(..., "Venus::Assert")
check
check(string $expr) (Venus::Check)
Returns a Venus::Check object based on the type expression provided.
Since 4.15
- check example 1
-
# given: synopsis; my $check = $type->check('string | number'); # bless(..., "Venus::Check")
coercion
coercion(string $expr) (Venus::Coercion)
Returns a Venus::Coercion object based on the type expression provided.
Since 4.15
- coercion example 1
-
# given: synopsis; my $coercion = $type->coercion('string | number'); # bless(..., "Venus::Coercion")
constraint
constraint(string $expr) (Venus::Constraint)
Returns a Venus::Constraint object based on the type expression provided.
Since 4.15
- constraint example 1
-
# given: synopsis; my $constraint = $type->constraint('string | number'); # bless(..., "Venus::Constraint")
generate_expression
generate_expression(arrayref $expr) (string)
Returns the type expression for the data structure (representing a type expression) provided.
Since 4.15
- generate_expression example 1
-
# given: synopsis; my $generate_expression = $type->generate_expression(["string"]); # "string"
- generate_expression example 2
-
# given: synopsis; my $generate_expression = $type->generate_expression(["either", "string", "number"]); # "string | number"
- generate_expression example 3
-
# given: synopsis; my $generate_expression = $type->generate_expression([ "tuple", "number", ["either", ["within", "arrayref", "hashref"], "arrayref"], "coderef", ]); # "tuple[number, within[arrayref, hashref] | arrayref, coderef]"
generate_signature
generate_signature(arrayref $expr) (string)
Returns the subroutine signature for the data structure (representing a subroutine signature) provided.
Since 4.15
- generate_signature example 1
-
# given: synopsis; my $generate_signature = $type->generate_signature(["output", [], []]); # "output() ()"
- generate_signature example 2
-
# given: synopsis; my $generate_signature = $type->generate_signature(["count", [], [["number"]]]); # "count() (number)"
- generate_signature example 3
-
# given: synopsis; my $generate_signature = $type->generate_signature(["count", [["coderef", "\$filter"]], [["number"]]]); # "count(coderef $filter) (number)"
generate_signature_input
generate_signature_input(arrayref $expr) (string)
Returns the subroutine signature input expression for the data structure (representing a subroutine signature input expression) provided.
Since 4.15
- generate_signature_input example 1
-
# given: synopsis; my $generate_signature_input = $type->generate_signature_input([["string", "\$string"]]); # "string $string"
- generate_signature_input example 2
-
# given: synopsis; my $generate_signature_input = $type->generate_signature_input([["string", "\$string"], ["number", "\$number"]]); # "string $string, number $number"
- generate_signature_input example 3
-
# given: synopsis; my $generate_signature_input = $type->generate_signature_input([ ["string", "\$string"], ["coderef", "\$filter"] ]); # "string $string, coderef $filter"
generate_signature_output
generate_signature_output(arrayref $expr) (string)
Returns the subroutine signature output expression for the data structure (representing a subroutine signature output expression) provided.
Since 4.15
- generate_signature_output example 1
-
# given: synopsis; my $generate_signature_output = $type->generate_signature_output([["string", "\$string"]]); # "string $string"
- generate_signature_output example 2
-
# given: synopsis; my $generate_signature_output = $type->generate_signature_output([["string", "\$string"], ["number", "\$number"]]); # "string $string, number $number"
- generate_signature_output example 3
-
# given: synopsis; my $generate_signature_output = $type->generate_signature_output([ ["string", "\$string"], ["coderef", "\$filter"] ]); # "string $string, coderef $filter"
new
new(hashref $data) (Venus::Type)
Constructs a new object.
Since 4.15
- new example 1
-
package main; use Venus::Type; my $type = Venus::Type->new; # bless({}, "Venus::Type")
parse_expression
parse_expression(string $expr) (arrayref)
Returns the parsed data structure based on the type expression provided.
Since 4.15
- parse_expression example 1
-
# given: synopsis; my $parse_expression = $type->parse_expression('string | number | Example'); # ["either", "string", "number", "Example"]
- parse_expression example 2
-
# given: synopsis; my $parse_expression = $type->parse_expression('scalarref | object + string'); # ["either", "scalarref", ["includes", "object", "string"]]
- parse_expression example 3
-
# given: synopsis; my $parse_expression = $type->parse_expression('within[arrayref, string | number]'); # ["within", "arrayref", ["either", "string", "number"]]
- parse_expression example 4
-
# given: synopsis; my $parse_expression = $type->parse_expression('attributes[name, string, age, number]'); # ["attributes", "name", "string", "age", "number"]
- parse_expression example 5
-
# given: synopsis; my $parse_expression = $type->parse_expression('tuple[string, arrayref, code]'); # ["tuple", "string", "arrayref", "code"]
- parse_expression example 6
-
# given: synopsis; my $parse_expression = $type->parse_expression('inherits[Example] + attributes[value, string]'); # ["includes", ["inherits", "Example"], ["attributes", "value", "string"]]
- parse_expression example 7
-
# given: synopsis; my $parse_expression = $type->parse_expression('consumes[Example::Role] | identity[Example]'); # ["either", ["consumes", "Example::Role"], ["identity", "Example"]]
- parse_expression example 8
-
# given: synopsis; my $parse_expression = $type->parse_expression('either[tuple[string, number], coderef]'); # ["either", ["tuple", "string", "number"], "coderef"]
- parse_expression example 9
-
# given: synopsis; my $parse_expression = $type->parse_expression('within[hashref, attributes["name", string]]'); # ["within", "hashref", ["attributes", "name", "string"]]
- parse_expression example 10
-
# given: synopsis; my $parse_expression = $type->parse_expression('maybe[arrayref] | either[scalar, code]'); # ["either", ["maybe", "arrayref"], ["either", "scalar", "code"]]
parse_signature
parse_signature(string $expr) (arrayref)
Returns the parsed data structure based on the subroutine signature provided.
Since 4.15
- parse_signature example 1
-
# given: synopsis; my $parse_signature = $type->parse_signature('print(string @values) (boolean)'); # ["print", [["string", "\@values"]], [["boolean"]]]
- parse_signature example 2
-
# given: synopsis; my $parse_signature = $type->parse_signature('chmod(string $mode) (Venus::Path)'); # ["chmod", [["string", "\$mode"]], [["Venus::Path"]]]
- parse_signature example 3
-
# given: synopsis; my $parse_signature = $type->parse_signature('copy(string | Venus::Path $path) (Venus::Path)'); # ["copy", [["string | Venus::Path", "\$path"]], [["Venus::Path"]]]
- parse_signature example 4
-
# given: synopsis; my $parse_signature = $type->parse_signature('find(string | regexp $expr) (within[arrayref, Venus::Path])'); # ["find", [["string | regexp", "\$expr"]], [["within[arrayref, Venus::Path]"]]]
- parse_signature example 5
-
# given: synopsis; my $parse_signature = $type->parse_signature('mkdir(maybe[string] $mode) (Venus::Path)'); # ["mkdir", [["maybe[string]", "\$mode"]], [[ "Venus::Path" ]]]
- parse_signature example 6
-
# given: synopsis; my $parse_signature = $type->parse_signature('open(any @data) (FileHandle)'); # ["open", [["any", "\@data"]], [["FileHandle"]]]
- parse_signature example 7
-
# given: synopsis; my $parse_signature = $type->parse_signature('root(string $spec, string $base) (maybe[Venus::Path])'); # ["root", [["string", "\$spec"], ["string", "\$base"]], [["maybe[Venus::Path]"]]]
- parse_signature example 8
-
# given: synopsis; my $parse_signature = $type->parse_signature('extension(string $name) (string | Venus::Path)'); # ["extension", [["string", "\$name"]], [["string | Venus::Path"]]]
- parse_signature example 9
-
# given: synopsis; my $parse_signature = $type->parse_signature('count()'); # Exception! isa Venus::Type::Error (see error_on_signature_parse)
- may raise Venus::Type::Error
on.signature.parse -
package main; use Venus::Type; my $type = Venus::Type->new; $type->parse_signature('count()'); # Error! (on.signature.parse)
parse_signature_input
parse_signature_input(string $expr) (arrayref)
Returns the parsed data structure for the input type expressions in the subroutine signature provided.
Since 4.15
- parse_signature_input example 1
-
# given: synopsis; my $parse_signature_input = $type->parse_signature_input('print(string @values) (boolean)'); # ["string"]
- parse_signature_input example 2
-
# given: synopsis; my $parse_signature_input = $type->parse_signature_input('chmod(string $mode) (Venus::Path)'); # ["string"]
- parse_signature_input example 3
-
# given: synopsis; my $parse_signature_input = $type->parse_signature_input('copy(string | Venus::Path $path) (Venus::Path)'); # ["string | Venus::Path"]
- parse_signature_input example 4
-
# given: synopsis; my $parse_signature_input = $type->parse_signature_input('find(string | regexp $expr) (within[arrayref, Venus::Path])'); # ["string | regexp"]
- parse_signature_input example 5
-
# given: synopsis; my $parse_signature_input = $type->parse_signature_input('mkdir(maybe[string] $mode) (Venus::Path)'); # ["maybe[string]"]
- parse_signature_input example 6
-
# given: synopsis; my $parse_signature_input = $type->parse_signature_input('open(any @data) (FileHandle)'); # ["any"]
- parse_signature_input example 7
-
# given: synopsis; my $parse_signature_input = $type->parse_signature_input('root(string $spec, string $base) (maybe[Venus::Path])'); # ["string", "string"]
- parse_signature_input example 8
-
# given: synopsis; my $parse_signature_input = $type->parse_signature_input('extension(string $name) (string | Venus::Path)'); # ["string"]
parse_signature_output
parse_signature_output(string $expr) (arrayref)
Returns the parsed data structure for the output type expression in the subroutine signature provided.
Since 4.15
- parse_signature_output example 1
-
# given: synopsis; my $parse_signature_output = $type->parse_signature_output('print(string @values) (boolean)'); # ["boolean"]
- parse_signature_output example 2
-
# given: synopsis; my $parse_signature_output = $type->parse_signature_output('chmod(string $mode) (Venus::Path)'); # ["Venus::Path"]
- parse_signature_output example 3
-
# given: synopsis; my $parse_signature_output = $type->parse_signature_output('copy(string | Venus::Path $path) (Venus::Path)'); # ["Venus::Path"]
- parse_signature_output example 4
-
# given: synopsis; my $parse_signature_output = $type->parse_signature_output('find(string | regexp $expr) (within[arrayref, Venus::Path])'); # ["within[arrayref, Venus::Path]"]
- parse_signature_output example 5
-
# given: synopsis; my $parse_signature_output = $type->parse_signature_output('mkdir(maybe[string] $mode) (Venus::Path)'); # ["Venus::Path"]
- parse_signature_output example 6
-
# given: synopsis; my $parse_signature_output = $type->parse_signature_output('open(any @data) (FileHandle)'); # ["FileHandle"]
- parse_signature_output example 7
-
# given: synopsis; my $parse_signature_output = $type->parse_signature_output('root(string $spec, string $base) (maybe[Venus::Path])'); # ["maybe[Venus::Path]"]
- parse_signature_output example 8
-
# given: synopsis; my $parse_signature_output = $type->parse_signature_output('extension(string $name) (string | Venus::Path)'); # ["string | Venus::Path"]
unpack
unpack(arrayref $args, arrayref $expr) (Venus::Unpack)
Returns a Venus::Unpack object based on the values and data structure (representing type expressions) provided.
Since 4.15
- unpack example 1
-
# given: synopsis; my $unpack = $type->unpack(["hello world"], ["string"]); # bless(..., "Venus::Unpack")
- unpack example 2
-
# given: synopsis; my $unpack = $type->unpack(["hello world"], ["string | number"]); # bless(..., "Venus::Unpack")
unpack_signature_input
unpack_signature_input(string $signature, arrayref $args) (Venus::Unpack)
Returns a Venus::Unpack object based on the values and data structure (representing a subroutine signature input expression) provided.
Since 4.15
- unpack_signature_input example 1
-
# given: synopsis; my $unpack_signature_input = $type->unpack_signature_input( 'output(string $error) (string)', ["hello world"], ); # bless(..., "Venus::Unpack")
- unpack_signature_input example 2
-
# given: synopsis; my $unpack_signature_input = $type->unpack_signature_input( 'output(string | number $error) (string)', ["hello world"], ); # bless(..., "Venus::Unpack")
unpack_signature_output
unpack_signature_output(string $signature, arrayref $args) (Venus::Unpack)
Returns a Venus::Unpack object based on the values and data structure (representing a subroutine signature output expression) provided.
Since 4.15
- unpack_signature_output example 1
-
# given: synopsis; my $unpack_signature_output = $type->unpack_signature_output( 'output(string $error) (string)', ["hello world"], ); # bless(..., "Venus::Unpack")
- unpack_signature_output example 2
-
# given: synopsis; my $unpack_signature_output = $type->unpack_signature_output( 'output(string | number $error) (string)', ["hello world"], ); # bless(..., "Venus::Unpack")
AUTHORS
Awncorp, awncorp@cpan.org
LICENSE
Copyright (C) 2022, Awncorp, awncorp@cpan.org.
This program is free software, you can redistribute it and/or modify it under the terms of the Apache license version 2.0.