{"id":7276,"date":"2022-12-20T19:37:34","date_gmt":"2022-12-20T22:37:34","guid":{"rendered":"http:\/\/lode.uno\/linux-man\/index.php\/2022\/12\/20\/specioconstraintsimple-man3\/"},"modified":"2022-12-20T19:37:34","modified_gmt":"2022-12-20T22:37:34","slug":"specioconstraintsimple-man3","status":"publish","type":"post","link":"https:\/\/lode.uno\/linux-man\/2022\/12\/20\/specioconstraintsimple-man3\/","title":{"rendered":"Specio::Constraint::Simple (man3)"},"content":{"rendered":"<h1 align=\"center\">Specio::Constraint::Simple<\/h1>\n<p> <a href=\"#NAME\">NAME<\/a><br \/> <a href=\"#VERSION\">VERSION<\/a><br \/> <a href=\"#SYNOPSIS\">SYNOPSIS<\/a><br \/> <a href=\"#DESCRIPTION\">DESCRIPTION<\/a><br \/> <a href=\"#API\">API<\/a><br \/> <a href=\"#OVERLOADING\">OVERLOADING<\/a><br \/> <a href=\"#ROLES\">ROLES<\/a><br \/> <a href=\"#SUPPORT\">SUPPORT<\/a><br \/> <a href=\"#SOURCE\">SOURCE<\/a><br \/> <a href=\"#AUTHOR\">AUTHOR<\/a><br \/> <a href=\"#COPYRIGHT AND LICENSE\">COPYRIGHT AND LICENSE<\/a> <\/p>\n<hr>\n<h2>NAME <a name=\"NAME\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">Specio::Constraint::Simple \u2212 Class for simple (non\u2212parameterized or specialized) types<\/p>\n<h2>VERSION <a name=\"VERSION\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">version 0.46<\/p>\n<h2>SYNOPSIS <a name=\"SYNOPSIS\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">my $str = t(&#8216;Str&#8217;); <br \/> print $str\u2212>name; # Str <br \/> my $parent = $str\u2212>parent; <br \/> if ( $str\u2212>value_is_valid($value) ) { &#8230; } <br \/> $str\u2212>validate_or_die($value); <br \/> my $code = $str\u2212>inline_coercion_and_check(&#8216;$_[0]&#8217;);<\/p>\n<h2>DESCRIPTION <a name=\"DESCRIPTION\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">This class implements simple type constraints, constraints without special properties or parameterization.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">It does not actually contain any real code of its own. The entire implementation is provided by the Specio::Constraint::Role::Interface role, but the primary <small>API<\/small> for type constraints is documented here.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">All other type constraint classes in this distribution implement this <small>API,<\/small> except where otherwise noted.<\/p>\n<h2>API <a name=\"API\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">This class provides the following methods.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>Specio::Constraint::Simple\u2212>new(&#8230;)<\/b> <br \/> This creates a new constraint. It accepts the following named parameters:<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"1%\">\n<p>\u2022<\/p>\n<\/td>\n<td width=\"5%\"><\/td>\n<td width=\"20%\">\n<p>name => $name<\/p>\n<\/td>\n<td width=\"63%\"> <\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:17%; margin-top: 1em\">This is the type\u2019s name. The name is optional, but if provided it must be a string.<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"1%\">\n<p style=\"margin-top: 1em\">\u2022<\/p>\n<\/td>\n<td width=\"5%\"><\/td>\n<td width=\"23%\">\n<p style=\"margin-top: 1em\">parent => $type<\/p>\n<\/td>\n<td width=\"60%\"> <\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:17%; margin-top: 1em\">The type\u2019s parent type. This must be an object which does the Specio::Constraint::Role::Interface role.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">This parameter is optional.<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"1%\">\n<p style=\"margin-top: 1em\">\u2022<\/p>\n<\/td>\n<td width=\"5%\"><\/td>\n<td width=\"38%\">\n<p style=\"margin-top: 1em\">constraint => sub { &#8230; }<\/p>\n<\/td>\n<td width=\"45%\"> <\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:17%; margin-top: 1em\">A subroutine reference implementing the constraint. It will be called as a method on the object and passed a single argument, the value to check.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">It should return true or false to indicate whether the value matches the constraint.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">This parameter is mutually exclusive with &#8220;inline_generator&#8221;.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">You can also pass this option with the key &#8220;where&#8221; in the parameter list.<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"1%\">\n<p style=\"margin-top: 1em\">\u2022<\/p>\n<\/td>\n<td width=\"5%\"><\/td>\n<td width=\"48%\">\n<p style=\"margin-top: 1em\">inline_generator => sub { &#8230; }<\/p>\n<\/td>\n<td width=\"35%\"> <\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:17%; margin-top: 1em\">This should be a subroutine reference which returns a string containing a single term. This code should <i>not<\/i> end in a semicolon. This code should implement the constraint.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">The generator will be called as a method on the constraint with a single argument. That argument is the name of the variable being coerced, something like &#8216;$_[0]&#8217; or &#8216;$var&#8217;.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">The inline generator is expected to include code to implement both the current type and all its parents. Typically, the easiest way to do this is to write a subroutine something like this:<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">sub { <br \/> my $self = shift; <br \/> my $var = shift; <br \/> return $_[0]\u2212>parent\u2212>inline_check( $_[1] ) <br \/> . &#8216; and more checking code goes here&#8217;; <br \/> }<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">This parameter is mutually exclusive with &#8220;constraint&#8221;.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">You can also pass this option with the key &#8220;inline&#8221; in the parameter list.<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"1%\">\n<p style=\"margin-top: 1em\">\u2022<\/p>\n<\/td>\n<td width=\"5%\"><\/td>\n<td width=\"37%\">\n<p style=\"margin-top: 1em\">inline_environment => {}<\/p>\n<\/td>\n<td width=\"46%\"> <\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:17%; margin-top: 1em\">This should be a hash reference of variable names (with sigils) and values for that variable. The values should be <i>references<\/i> to the values of the variables.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">This environment will be used when compiling the constraint as part of a subroutine. The named variables will be captured as closures in the generated subroutine, using Eval::Closure.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">It should be very rare to need to set this in the constructor. It\u2019s more likely that a special type subclass would need to provide values that it generates internally.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">If you do set this, you are responsible for generating variable names that won\u2019t clash with anything else in the inlined code.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">This parameter defaults to an empty hash reference.<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"1%\">\n<p style=\"margin-top: 1em\">\u2022<\/p>\n<\/td>\n<td width=\"5%\"><\/td>\n<td width=\"49%\">\n<p style=\"margin-top: 1em\">message_generator => sub { &#8230; }<\/p>\n<\/td>\n<td width=\"34%\"> <\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:17%; margin-top: 1em\">A subroutine to generate an error message when the type check fails. The default message says something like &#8220;Validation failed for type named Int declared in package Specio::Library::Builtins (&#8230;\/Specio\/blib\/lib\/Specio\/Library\/Builtins.pm) at line 147 in sub named (eval) with value 1.1&#8221;.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">You can override this to provide something more specific about the way the type failed.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">The subroutine you provide will be called as a subroutine, <i>not as a method<\/i>, with two arguments. The first is the description of the type (the bit in the message above that starts with &#8220;type named Int &#8230;&#8221; and ends with &#8220;&#8230; in sub named (eval)&#8221;. This description says what the thing is and where it was defined.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">The second argument is the value that failed the type check, after any coercions that might have been applied.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">You can also pass this option with the key &#8220;message&#8221; in the parameter list.<\/p>\n<table width=\"100%\" border=\"0\" rules=\"none\" frame=\"void\" cellspacing=\"0\" cellpadding=\"0\">\n<tr valign=\"top\" align=\"left\">\n<td width=\"11%\"><\/td>\n<td width=\"1%\">\n<p style=\"margin-top: 1em\">\u2022<\/p>\n<\/td>\n<td width=\"5%\"><\/td>\n<td width=\"41%\">\n<p style=\"margin-top: 1em\">declared_at => $declared_at<\/p>\n<\/td>\n<td width=\"42%\"> <\/td>\n<\/tr>\n<\/table>\n<p style=\"margin-left:17%; margin-top: 1em\">This parameter must be a Specio::DeclaredAt object.<\/p>\n<p style=\"margin-left:17%; margin-top: 1em\">This parameter is required.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">It is possible to create a type without a constraint of its own.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>name<\/b> <br \/> Returns the name of the type as it was passed the constructor.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>parent<\/b> <br \/> Returns the parent type passed to the constructor. If the type has no parent this returns &#8220;undef&#8221;.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>is_anon<\/b> <br \/> Returns false for named types, true otherwise.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>is_a_type_of($other_type)<\/b> <br \/> Given a type object, this returns true if the type this method is called on is a descendant of that type or is that type.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>is_same_type_as($other_type)<\/b> <br \/> Given a type object, this returns true if the type this method is called on is the same as that type.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>coercions<\/b> <br \/> Returns a list of Specio::Coercion objects which belong to this constraint.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>coercion_from_type($name)<\/b> <br \/> Given a type name, this method returns a Specio::Coercion object which coerces from that type, if such a coercion exists.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>validate_or_die($value)<\/b> <br \/> This method does nothing if the value is valid. If it is not, it throws a Specio::Exception.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>value_is_valid($value)<\/b> <br \/> Returns true or false depending on whether the $value passes the type constraint.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>has_real_constraint<\/b> <br \/> This returns true if the type was created with a &#8220;constraint&#8221; or &#8220;inline_generator&#8221; parameter. This is used internally to skip type checks for types that don\u2019t actually implement a constraint.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>description<\/b> <br \/> This returns a string describing the type. This includes the type\u2019s name and where it was declared, so you end up with something like &#8216;type named Foo declared in package My::Lib (lib\/My\/Lib.pm) at line 42&#8217;. If the type is anonymous the name will be &#8220;anonymous type&#8221;.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>id<\/b> <br \/> This is a unique id for the type as a string. This is useful if you need to make a hash key based on a type, for example. This should be treated as an essentially arbitrary and opaque string, and could change at any time in the future. If you want something human-readable, use the &#8220;$type\u2212>description&#8221; method.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>add_coercion($coercion)<\/b> <br \/> This adds a new Specio::Coercion to the type. If the type already has a coercion from the same type as the new coercion, it will throw an error.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>has_coercion_from_type($other_type)<\/b> <br \/> This method returns true if the type can coerce from the other type.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>coerce_value($value)<\/b> <br \/> This attempts to coerce a value into a new value that matches the type. It checks all of the type\u2019s coercions. If it finds one which has a &#8220;from&#8221; type that accepts the value, it runs the coercion and returns the new value.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">If it cannot find a matching coercion it returns the original value.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>inline_coercion_and_check($var)<\/b> <br \/> Given a variable name, this returns a string of code and an environment hash that implements all of the type\u2019s coercions as well as the type check itself.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">This will throw an exception unless both the type and all of its coercions are inlinable.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The generated code will throw a Specio::Exception if the type constraint fails. If the constraint passes, then the generated code returns the (possibly coerced) value.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The return value is a two-element list. The first element is the code. The second is a hash reference containing variables which need to be in scope for the code to work. This is intended to be passed to Eval::Closure\u2019s &#8220;eval_closure&#8221; subroutine.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The returned code is a single &#8220;do { }&#8221; block without a terminating semicolon.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>inline_assert($var)<\/b> <br \/> Given a variable name, this generates code that implements the constraint and throws an exception if the variable does not pass the constraint.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The return value is a two-element list. The first element is the code. The second is a hash reference containing variables which need to be in scope for the code to work. This is intended to be passed to Eval::Closure\u2019s &#8220;eval_closure&#8221; subroutine.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>inline_check($var)<\/b> <br \/> Given a variable name, this returns a string of code that implements the constraint. If the type is not inlinable, this method throws an error.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>inline_coercion($var)<\/b> <br \/> Given a variable name, this returns a string of code and an environment hash that implements all of the type\u2019s coercions. <i>It does not check that the resulting value is valid.<\/i><\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">This will throw an exception unless all of the type\u2019s coercions are inlinable.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The return value is a two-element list. The first element is the code. The second is a hash reference containing variables which need to be in scope for the code to work. This is intended to be passed to Eval::Closure\u2019s &#8220;eval_closure&#8221; subroutine.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The returned code is a single &#8220;do { }&#8221; block without a terminating semicolon.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>inline_environment()<\/b> <br \/> This returns a hash defining the variables that need to be closed over when inlining the type. The keys are full variable names like &#8216;$foo&#8217; or &#8216;@bar&#8217;. The values are <i>references<\/i> to a variable of the matching type.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\"><b>$type\u2212>coercion_sub<\/b> <br \/> This method returns a sub ref that takes a single argument and applied all relevant coercions to it. This sub ref will use Sub::Quote if all the type\u2019s coercions are inlinable.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">This method exists primarily for the benefit of Moo.<\/p>\n<h2>OVERLOADING <a name=\"OVERLOADING\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">All constraints overloading subroutine de-referencing for the benefit of Moo. The returned subroutine uses Sub::Quote if the type constraint is inlinable.<\/p>\n<h2>ROLES <a name=\"ROLES\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">This role does the Specio::Constraint::Role::Interface and Specio::Role::Inlinable roles.<\/p>\n<h2>SUPPORT <a name=\"SUPPORT\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">Bugs may be submitted at <https:\/\/github.com\/houseabsolute\/Specio\/issues>.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">I am also usually active on <small>IRC<\/small> as \u2019autarch\u2019 on &#8220;irc:\/\/irc.perl.org&#8221;.<\/p>\n<h2>SOURCE <a name=\"SOURCE\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">The source code repository for Specio can be found at <https:\/\/github.com\/houseabsolute\/Specio>.<\/p>\n<h2>AUTHOR <a name=\"AUTHOR\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">Dave Rolsky <autarch@urth.org><\/p>\n<h2>COPYRIGHT AND LICENSE <a name=\"COPYRIGHT AND LICENSE\"><\/a> <\/h2>\n<p style=\"margin-left:11%; margin-top: 1em\">This software is Copyright (c) 2012 \u2212 2020 by Dave Rolsky.<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">This is free software, licensed under:<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The Artistic License 2.0 (GPL Compatible)<\/p>\n<p style=\"margin-left:11%; margin-top: 1em\">The full text of the license can be found in the <i><small>LICENSE<\/small><\/i> file included with this distribution.<\/p>\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>  Specio::Constraint::Simple \u2212 Class for simple (non\u2212parameterized or specialized) types <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[3007,3600],"class_list":["post-7276","post","type-post","status-publish","format-standard","hentry","category-sin-categoria","tag-man3","tag-specioconstraintsimple"],"gutentor_comment":0,"_links":{"self":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/posts\/7276","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/comments?post=7276"}],"version-history":[{"count":0,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/posts\/7276\/revisions"}],"wp:attachment":[{"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/media?parent=7276"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/categories?post=7276"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lode.uno\/linux-man\/wp-json\/wp\/v2\/tags?post=7276"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}