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

NAME

Devel::Ladybug::Type - Devel::Ladybug::Object data type assertions

SYNOPSIS

Typing rules for instance variables are asserted in class prototypes, as inline keys:

  use Devel::Ladybug qw| :all |;

  create "YourApp::Example" => {
    #
    # Instance variable "foo" will contain optional string data:
    #
    foo => Devel::Ladybug::Str->assert(
      subtype(
        optional => true
      )
    ),

    ...
  };

More examples may be found in Devel::Ladybug::Class, and in the documentation for specific object classes.

DESCRIPTION

Devel::Ladybug::Type subclasses describe rules which Devel::Ladybug::Object instance variables must conform to.

If a caller tries to do something contrary to a Type assertion, Devel::Ladybug will throw an exception, which causes an exit unless caught using eval/$@ or try/catch (see Error).

Dynamic Subclasses

The "built-in" subclasses derived from Devel::Ladybug::Type and Devel::Ladybug::Subtype are auto-generated, and have no physical modules.

Types may be modified by Subtypes via the subtype function. See SUBTYPE ARGS, in this document, for more details and a list of these rule types. Subtype subclasses are allocated from the definitions found in the %Devel::Ladybug::Type::RULES package variable.

SUBTYPE ARGS

Many subtype args affect database schema attributes. If changed after the table exists, the table should be re-created or altered.

Instance variable assertions may be modified by providing the following arguments to subtype():

columnType => $colType

Override a database column type, eg "VARCHAR(128)".

default => $value

Set the default value for a given instance variable and database table column.

deleteRefOpt => $option

(MySQL only) Set the foreign constraint reference option for DELETE operations

indexed => $bool

Enable full-text indexing for this column. This is an experimental feature.

min => $num

Specifies the minimum allowed numeric value for a given instance variable.

minSize => $num

Specifies the minimum length or scalar size for a given instance variable.

max => $num

Specifies the maximum allowed numeric value for a given instance variable.

maxSize => $num

Specifies the maximum length or scalar size for a given instance variable.

optional => $bool

Permit a NULL (undef) value for a given instance variable.

regex => qr/.../

Specifies an optional regular expression which the value of the given instance variable must match.

size => $num

Specify that values must always be of a fixed size. The "size" is the value obtained through the built-in function length() (string length) for Scalars, scalar(...) (element count) for Arrays, and scalar keys() (key count) for Hashes.

sqlValue => $str, sqlInsertValue => $str, sqlUpdateValue => $str

Override an asserted attribute's "insert" value when writing to a SQL database. This is useful if deriving a new value from existing table values at insertion time.

::sqlInsertValue and ::sqlUpdateValue override any provided value for ::sqlValue, but only on INSERT and UPDATE statements, respectively.

  create "YourApp::Example" => {
    foo => Devel::Ladybug::Int->assert(...,
      subtype(
        sqlValue => "(coalesce(max(foo),-1)+1)",
      )
    ),

    # ...
  };

unique => $bool

Specify UNIQUE database table columns.

  create "YourApp::Example" => {
    #
    # Your must either specify true or false...
    #
    foo => Devel::Ladybug::Str->assert(...,
      subtype(
        unique => true
      )
    ),

    #
    # ... or specify a name for "joined" combinatory keys,
    # as used in statement UNIQUE KEY ("foo","bar")
    #
    # To join with more than one key, provide an array reference
    # of key names.
    #
    # For example, to make sure bar+foo is always unique:
    #
    bar => Devel::Ladybug::Str->assert(...,
      subtype(
        unique => "foo"
      )
    ),

    # ...
  };

updateRefOpt => $option

(MySQL only) Set the foreign constraint reference option for UPDATE operations

TEST SUBS

The remainder of this doc contains information which is generally only useful if hacking on core Devel::Ladybug internals.

These subs are defined as package constants, and are used internally by Devel::Ladybug. These subs are not for general usage, but for coding Devel::Ladybug internals.

Each returns a CODE block which may be used to validate data types.

When executed, the test subs throw a Devel::Ladybug::AssertFailed exception on validation failure, and return true on success.

  • insist($value, Code $test);

    Runs the received value against a test sub.

      #
      # Devel::Ladybug will agree, $str is string-like.
      #
      my $str = "Hello";
    
      insist($str, Devel::Ladybug::Type::isStr);
    
      #
      # This will throw an exception:
      #
      my $notStr = { };
    
      insist($notStr, Devel::Ladybug::Type::isStr);
  • isStr(Str $value)

    Returns a CODE ref which tests the received value for string-ness.

  • isFloat(Num $value)

    Returns a CODE ref which tests the received value for float-ness.

  • isInt(Num $value)

    Returns a CODE ref which tests the received value for int-ness.

  • isArray(Array $value)

    Returns a CODE ref which tests the received value for array-ness.

  • isBool(Bool $value)

    Returns a CODE ref which tests the received value for bool-ness.

  • isCode(Code $code)

    Returns a CODE ref which tests the received value for CODE-ness.

  • isHash(Hash $value)

    Returns a CODE ref which tests the received value for hash-ness.

  • isRef(Ref $ref)

    Returns a CODE ref which tests the received value for ref-ness.

  • isRule(Rule $rule)

    Returns a CODE ref which tests the received value for regex-ness.

  • isScalar(Str $scalar)

    Returns a CODE ref which tests the received value for scalar-ness.

PUBLIC CLASS METHODS

These methods are used internally by Devel::Ladybug at a low level, and normally won't be accessed directly.

If creating a new Type subclass from scratch, its constructors and methods would need to implement this interface.

  • $class->new(%args)

    Instantiate a new Devel::Ladybug::Type object.

    This method is called internally when the assert method is called for an object class. It does not typically need to be used directly.

READ-ONLY ATTRIBUTES

Although these are public-ish, there normally should not be a need to access them directly.

  • $type->allowed($value)

    Returns true if the received value is allowed, otherwise throws an exception.

  • $type->code()

    Returns the CODE ref used to test this attribute's value for correctness. The code ref is a sub{ } block which takes the value as an argument, and returns a true or false value.

  • $type->memberType()

    Used for Arrays only. Returns a "sub-assertion" (another Devel::Ladybug::Type object) which is unrolled for array elements.

  • $type->memberClass()

    Used for Devel::Ladybug::ExtID assertions only. Returns the name of the class which this attribute is a pointer to.

  • $type->externalClass()

    Convenience wrapper for memberClass, but also works for Arrays of ExtIDs. One-to-one foreign keys are asserted as ExtID, but one-to-many keys are an ExtID assertion wrapped in an Array assertion. This means a lot of double-checking in code later, so this method exists to handle both cases without fuss.

    Used for Devel::Ladybug::ExtID assertions (one-to-one) and Devel::Ladybug::Array assertions encapsulating an ExtID, to return the name of the class which the current attribute is a pointer to.

  • $type->objectClass()

    Returns the concrete object class which this type is for.

PUBLIC INSTANCE METHODS

  • $self->class()

    Object wrapper for Perl's built-in ref() function

  • $type->test($key, $value)

    Send the received value to the code reference returned by $type->code(). Warns and returns a false value on test failure, otherwise returns true.

    $key is included so the caller may know what the warning was for!

    XXX TODO The individual tests need moved out of this monolithic sub, and into the assertion code tests. Will make things cleaner and faster.

SEE ALSO

Devel::Ladybug::Class, Devel::Ladybug::Subtype

This file is part of Devel::Ladybug.

REVISION

$Id: $