The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Types::Core - Core types defined as tests and literals (ease of use)


Version "0.3.2";


  my @data_types = (ARRAY CODE GLOB HASH IO REF SCALAR);
  my $ref = $_[0];
  P "Error: expected %s", HASH unless HASH $ref;

Syntax symplifier for type checking.

Allows easy, unquoted use of var types (ARRAY, SCALAR, etc.) as literals, and allows standard type names to be used as boolean checks of the type of a reference as well as passing through the value of the reference. For example: HASH $href will return true if the reference points to a HASH or a HASH-based object. For example, "HASH $href" check routines of references.


    TYPE <Ref> - Check if Ref has underlying type, TYPE

    TYPE - Literal usage equal to itself


  printf "type = %s\n", HASH if HASH $var;

Same as:

  printf "type = %s\n", 'HASH' if ref $var eq 'HASH';)


For the most basic functions listed in the Synopsis, they take either 0 or 1 arguments. If 1 parameter, then they test it to see if the ref is of the given type (blessed or not). If false, undef is returned, of true, the ref, itself is returned.

For no args, they return literals of themselves, allowing the named strings to be used as Literals w/o quotes.



  our %field_types = (Paths{type => ARRAY, ...});

Flow Routing

    my $ref_arg = ref $arg;
    return  ARRAY $ref_arg            ? StatAR_2_Ino_t($path,$arg)  :
            InClass(Stat_t, $ref_arg) ? Stat_t_2_Ino_t($path, $arg) :
            _path_2_Ino_t($path); }

Create Class function as constant and to test membership

                sub Stat(;*);                   # needed for prototype
                local * Stat = InClass Stat;
                my $p=bless [], Task;
                P "p isa %s", Task if Task $p;

Data Verification

  sub Type_check($;$) { ...
    if (ARRAY $cfp) { 
      for (@$cfp) { 
        die P "Field %s does not exist", $_ unless exists $v->{$_}; 
        my $cls_ftpp = $class."::field_types"; 
        if (HASH $cls_ftpp) { 
          if ($cls_ftpp->{type} eq ARRAY) {  ...

Param Checking

  sub popable (+) { 
    my $ar = $_[0]; 
    ARRAY $ar or die P "popable only works with arrays, not %s", ref $ar; }

Return Value Checks and Dereference Protection

  my $Inos = $mp->get_sorted_Ino_t_Array; 
  return undef unless ARRAY $Inos and @$Inos >= 2;

Non-instantiating existence checks in references: ErV.

     ErV $ref, FIELDNAME;        # Exist[in]reference? Value : C<undef>
     ErV $hashref, FIELDNAME;    # Exist[in]hashref?   Value : C<undef>

    If fieldname exists in the ref pointed to by the reference, return the value, else return undef.

Note: What's EhV? (Deprecated)

      You may see older code using C<EhV>.  M<Types::Core> only had this checker
      for hashes, but given combinations of various references, the more
      general C<ErV> replaced it.


     typ REF;                    #return underlying type of REF

Once you bless a reference to an object, its type becomes hidden from ref. typ allows you to peek into a class reference to see the basic perl type that the class is based on.

Most users of a class won't have a need for that information, but a 'friend' of the class might in order to offer helper functions.

    blessed REF;                #test if REF is blessed or not

Needed for consistency with 'ref' (and typ). 'ref' passes back the actual value of the 'ref' if it is a ref. Following that example, 'typ' return the underlying type of a perl-ref if it is a reference. In the same way, 'blessed' returns the name of the object's blessing (its class or package name) if it is 'blessed'.

Warning: take care that Scalar::Util's version of blessed isn't also included, as it throws away the package or blessing name and only returns '1' if its argument is blessed. perl-type of a reference if it is a reference.Included for it's usefulness in type checking. Similar functionality as implemented in Scalar::Util. This version of blessed will use the Scalar::Util version if it is already present. Otherwise it uses a pure-perl implementation.


To prevent automatic creation of variables when accessed or tested for undef, (i.e. autovivification), one must test for existence first, before attempting to read or test the 'defined'-ness of the value.

This results in a 2 step process to retrive a value:

  exists $name{$testname} ? $name{testname} : undef;

If you have multiple levels of hash tables say retrieving SSN's via {$lastname}{$firstname} in object member 'name2ssns' but don't know if the object member is valid or not, the safe way to write this would be:

  my $p = $this;
  if (exists $p->{name2ssns} && defined $p->{name2ssns}) {
    $p = $p->{name2ssns};
    if (exists $p->{$lastname} && defined $p->{$lastname}) {
      $p = $p->{$lastname};
      if (exists $p->{$firstname}) {
        return $p->{$firstname};
  return undef;

ErV saves some steps. Instead of testing for existence, 'definedness', and then use the value to go deeper in the structuer, ErV does the testing and returns the value (or undef) in one step. Thus, the above could be written:

  my $p = $this;
  return $p = ErV $p, name2ssns      and
             $p = ErV $p, $lastname  and 
                  ErV $p, $firstname;

This not only saves coding space & time, but allows faster comprehension of what is going on (presuming familiarity with ErV).

Multiple levels of hashes or arrays may be tested in one usage. Example:

  my $nested_refs = {};
  $nested_refs->{a}{b}{c}{d}[2]{f}[1] = 7;
  P "---\nval=%s", ErV $nested_refs, a, b, c, d, e, f, g;

  The current ErV handles around thirty levels of nested references

MORE OPTIONAL FUNCTIONS mk_array and mk_hash

$< >

    mk_array $p->ar;

without mk_array, the following generates a runtime error (can't use an undefined value as an ARRAY reference):

    my $ar;
    printf "items in ar:%s\n", 0+@{$ar};

but using mk_array will ensure there is an ARRAY ref there if there is not one there already:

    my $ar;
    mk_array $ar;
    printf "items in ar:%s\n", 0+@{$ar};

While the above would be solved by initalizing $ar when defined, expicit initialization might be useful to protect against the same type of error in dynamically allocated variables.


     isnum STR              #return <NUM> if it starts at beginning of STR

     Cmp [$p1,$p2]          # C<cmp>-like function for nested structures
                            # uses C<$a>, C<$b> as default inputs
                            # can be used in sort for well-behaved data
                            # (incompare-able data will return undef)
                            # builtin debug to see where compare fails

isnum checks for a number (int, float, or with exponent) as the value of the string passed in. With no argument uses $_ as the parameter. Returns the number or undef if the field does not evaluate to a number. isnum is an optional import that must be mentioned in the modules arguments. Note: to determine if false, you must use defined(isnum) since numeric '0' can be returned and also evaluates to false.

The existence of Cmp is a side effect of testing needs. To compare validity of released functions, it was necessary to recursively compare nested data structures. To support development, debug output was added that can be toggled on at runtime to see where a compare fails.

Normally you only use two parameters $a and $b that are references to the data structures to be compared. If debugging is wanted, a third (or first if $a and $b are used) parameter can be pass with a non-zero value to enable primitive debug output.

Additionally, if the compare fails and does not return an integer value (returning undef instead), a 2nd return value can tell you where in the compare it failed. To grab that return value, use a two element list or an array to catch the status, like

  C<my ($result, $err)=Cmp; (pointers passed in C<$a> and C<$b>)

If the compare was successful, it will return -1, 0 or 1 as 'cmp' does. If it fails, $result will contain undef and $err will contain a number indicating what test failed (for debugging purposes).

Failures can occur if Cmp is asked to compare different object with different refs ('blessed' refname), or same blessed class and different underlying types. Unblessed values and those of the same class can be compared.

COMPATIBILITY NOTE: with Perl 5.12.5 and earlier

    In order for earlier perls to parse things correctly parentheses are needed for two or more arguments after a ErV test verb.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 654:

=over without closing =back