NAME

Data::Sah::Compiler::BaseProg - Base class for programming language compilers

VERSION

version 0.03

SYNOPSIS

DESCRIPTION

This class is used as base class for compilers which compile schemas into validators in programming language targets, like Data::Sah::Compiler::perl and Data::Sah::Compiler::js. The generated code by the compiler will be able to validate data according to the source schema.

Aside from Perl and JavaScript, this base class is also suitable for generating validators in other procedural languages, like PHP, Python, and Ruby. See CPAN if compilers for those languages exist.

Compilers using this base class are usually flexible in the kind of code they produce:

  • configurable validator form

    Simple schema can be compiled into validator in the form of a single expression (e.g. '$data >= 1 && $data <= 10') for the least amount of overhead. More complex schema can be compiled into full subroutines.

  • configurable validator return type

    Can generate validator that returns a simple bool result, str, or full obj.

  • configurable data term

    For flexibility in combining the validator code with other code, e.g. in sub wrapper (one such application is in Sub::Spec::Wrapper).

Planned future features include:

  • generating other kinds of code (aside from validators)

    Perhaps data compliance measurer, data transformer, or whatever.

This class is derived from Data::Sah::Compiler::BaseCompiler.

(CLASS INSTANCE) ATTRIBUTES

sub_prefix => STR

Prefix to use for generated subroutines. Default to 'sah_'.

CLASS ATTRIBUTES

indent_width => INT

Specify how many spaces indents in the target language are. Each programming language subclass will set this, for example the perl compiler sets this to 4 while js sets this to 2.

comment_style => STR

Specify how comments are written in the target language. Either 'c++' (// comment), 'shell' (# comment), 'c' (/* comment */), or 'ini' (; comment). Each programming language subclass will set this, for example, the perl compiler sets this to 'shell' while js sets this to 'c++'.

METHODS

new() => OBJ

$c->compile(%args) => HASH

Aside from BaseCompiler's arguments, this class supports these arguments (suffix * denotes required argument):

  • code_type => STR

    The kind of code to generate. For now the only valid (and default) value is 'validator'. Compiler can perhaps generate other kinds of code in the future.

  • validator_form* => STR

    Specify in what form the generated validator should take. Either 'expr', 'statements', or 'sub' is accepted.

    'expr' means an expression should be generated. For example, perl compiler will compile the schema ['str*', min_len=>8] into something like:

    # When C<validator_return_type> is 'bool'
    (!ref($data) && defined($data) && length($data))

    or:

    # When C<validator_return_type> is 'str'
    (ref($data) ? "Data not a string" :
        !defined($data) ? "Data required" :
            length($data) < 8 ? "Length of data minimum 8")

    'statements' means one or more statements should be generated. For example, the same schema will be compiled into something like:

    # When C<validator_return_type> is 'bool'
    return 0 if ref($data);
    return 0 unless defined($data);
    return 0 unless length($data) >= 8;
    return 1;

    'sub' means a subroutine should be generated. For example, the same schema will be compiled into something like:

    # When C<validator_return_type> is 'bool'
    sub sah_str1 {
        my ($data) = @_;
        return 0 if ref($data);
        return 0 unless defined($data);
        return 0 unless length($data) >= 8;
        return 1;
    }

    Different validator_form can be useful in different situation. For very simple schemas, outputting an expression will produce the most compact and low-overhead code which can also be combined in more ways with other external code. However, not all schemas can be output as simple expression, especially more complex ones.

    If validator_form request cannot be fulfilled, code will be output in another form as the compiler sees fit. You should check the validator_form key in the compiler return to know what form the result is. There's also requires and subs.

  • validator_return_type* => STR

    Specify what kind of return value the generated code should produce. Either 'bool', 'str', or 'obj'.

    'bool' means generated validator code should just return 1/0 depending on whether validation succeeds/fails.

    'str' means validation should return an error message string (the first one encountered) if validation fails and an empty string/undef if validation succeeds.

    'obj' means validation should return a full result object (see Data::Sah::Result). From this object you can check whether validation succeeds, retrieve all the collected errors/warnings, etc.

    Limitation: If validator_form is 'expr', validator_return_type usually can only be 'bool' or 'str'.

Return. Aside from result key which is the final code string, there are also modules (an arrayref) which is a list of module names that are required by the code (e.g. ["Scalar::Utils", "List::Util"]), subs (an arrayref) which contains subroutine name and definition code string, if any (e.g. [sah_zero = 'sub sah_zero { $_[0] != 0 }', sah_nonzero => 'sub sah_nonzero { $_[0] != 0 }']>. For flexibility, you'll need to do this bit of arranging yourself to get the final usable code you can compile in your chosen programming language. But there are usually shortcuts provided

SUBCLASSING

AUTHOR

Steven Haryanto <stevenharyanto@gmail.com>

COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Steven Haryanto.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.