The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

    Attribute::Method::Typeable - This module implements a series of attribute handler methods for use with function and method argument checking

SYNOPSIS

    package MyClass;

    use mixin qw{  Attribute::Method::Typeable };

    #or

    use base qw{ Attribute::Method::Typeable };

    sub myMethod :Public( int int ) {
        my $self = shift;
        my ($a, $b) = @_;
        return $a + $b;
    }

    sub otherMethod :Public( OtherClass SomeClass ) {
        my $self = shift;
        my ($obj1, $obj2) = @_;
        # methody stuff here.
    }

    sub privateMethod :Private( scalar, Scalar, SCALAR ) {
        my $self = shift;
        my $literal = shift;
        my $litOrRef = shift;
        my $scalarRef = shift;

        # methody stuff.
    }

    sub protectedMethod :Protected( other ) {
        my $self = shift;
        my $anything = shift;
        # methody stuff.
    }

    sub functiony :Function( ARRAY, CODE, HASH ) {
        # functiony stuff here.
        my ($arrayRef, $codeRef, $hashRef) = @_;
    }

    sub functionz :Function( float ARRAY o list ) {
        my ($arg1, $arg2, @else) = @_;
        $arg2->[0] = $arg1;
        if(scalar(@else)) {}
        # other functiony stuff.
    }

    ### In your code:

    # okay:
    $object->myMethod( 1, 2 );

    # throws an Exception::ParamError exception:
    $object->myMethod( 1, "apple" );

    # also throws an Exception::ParamError exception:
    $object->myMethod( 7 );

    # throws an Exception::MethodError exception:
    myMethod('MyClass', 3, 4 );

    # also throws an Exception::MethodError exception
    # unless it's in MyClass:
    $object->privateMethod( OtherClass->new, SomeClass->new );

    # also throws an Exception::MethodError exception
    # unless it's in MyClass or a subclass of MyClass:
    $object->protectedMethod( $thingy );

EXPORTS

Nothing by default.

REQUIRES

perl version 5.8.0, Attribute::Handlers, Data::Types, Test::SimpleUnit, Scalar::Util, Hook::WrapSub, Exception::Class, and optionally the mixin modules.

DESCRIPTION

This module implements a number of attribute handlers for use in argument checking. It provides attributes which differentiate between functions, public methods, protected methods, and private methods. It throws an exception in the case of an incorrect usage. Basically, these exceptions are meant to alert you of an incorrect calling of your methods or functions. Use of these attributes is also self-documenting.

ATTRIBUTES

As these are attributes, they go after the name of the function or method (i.e. subroutine name) but before the first curly brace. You simply specify the type of the subroutine (kinda like in more strongly typed languages), and any arguments that that subroutine takes. Below is a description of the available attributes.

:Function

This attribute specifies that the subroutine is a simple function. Since it is a function there is no need to verify that the caller has permission to call it, so the only things that are checked are the arguments. An exception will be thrown if any of the required arguments are missing or if the arguments are of the incorrect type.

:Constructor

This attribute specifies that the subroutine is a constructor. This means that it expects as it's first argument either an object or a class. Any additional arguments to the constructor are also checked. It is also assumed that a Constructor is Public in nature.

:Public

This attribute specifies that the subroutine is a public method. The first thing that is checked is that the first argument to this subroutine is in fact an object of the appropriate class. The arguments are also checked for validity, but since it is public, the caller is not checked. An exception is thrown if the first object is missing or not an object of the correct class, or if any of the required arguments are missing or if the arguments are of the incorrect type.

:Protected

This attribute specifies that the subroutine is a protected method. An exception is thrown if the first argument to a subroutine specified with this attribute is not an object of the appropriate class. Next the caller of the method is checked to be sure that it is either the class it was defined in itself or inherits from that class, an exception is thrown otherwise. Finally, each of the argument types is checked and an exception is thrown if an argument is of the wrong type or is missing if required.

:Private

This attribute specifies that the subroutine is a private method. The first argument is checked to be sure that it is an object of the appropriate type, an exception is thrown otherwise. The second thing that is checked is whether the caller of the method is the class that initially defined it, if not an exception is thrown. Finally, the arguments are checked for correct type and to be sure that all required arguments are present.

:Class

This attribute specifies that the subroutine is a class method. The program expects the first argument to be either the class (or an instance of the class) that it was defined in or a subclass of that class. Arguments are also checked for validity.

:Abstract

This attribute specifies that the subroutine is an abstract method. This means that the method is simply there to define an interface and should never be called directly, if it is an Exception::MethodError will be thrown.

:Virtual

This attribute is a synonym for :Abstract.

ARGUMENTS

The arguments to the attributes are specified within parenthesis. The arguments can be separated either with spaces or with commas. The case of the argument is important, because the program assumes that certain values in all caps correspond to the standard perl references. Below is a description of the available argument types.

whole

This specifies that the argument must be of whole number type, that is it must be a counting number.

int/integer

This specifies that the argument must be of integer number type, that means it includes zero and negative numbers.

decimal

This specifies that the argument must be of decimal number type, that is it can contain a decimal point, and be positive or negative.

real

This specifies that the argument must be of real number type, that is it can contain a decimal point, and be positive or negative.

float

This specifies that the argument must be of float number type, that is it can contain a decimal point, and be positive or negative, it can also contain an exponential notation.

char/character

This specifies that the argument must be a single character such as 'q', "r" or 2.

string

This specifies that the argument must be a string of characters, like 'foo', "bar" or 11234.334.

scalar/literal

This specifies that the argument can be any literal data, but not a reference.

Scalar

This specifies that the argument can either be a literal data item or a SCALAR reference.

SCALAR

This specifies that the argument to the subroutine will be a SCALAR reference.

ARRAY

This attribute argument indicates that the subroutine thus defined must recieve an array reference as an argument. For lists or literal arrays, see the list argument.

HASH

If this attribute argument is used, then the subroutine will accept only a hash reference for an argument in this position. For lists or literal hashes, see the list argument.

CODE

The attribute argument CODE signifies that the subroutine will accept a subroutine reference as an argument.

list/vector

The list attribute argument indicates that the subroutine will accept a series of values of any type. The list attribute argument must come after all other attribute arguments or an error will be thrown (unfortunately, this error is not currently caught at the time of compilation of the code implementing the method-prototyped attributes). The list attribute argument should be used when it is desired to pass an array or hash by value instead of by reference. It can also be used to specify that the subroutine can accept multiple arguments of any type. The list attribute argument indicates that the subroutine must have at least one argument, but could have nearly any number of arguments (limited by available memory). If a variable type argument is needed in the middle of stronger typed arguments, the attribute argument 'other' should be used.

other

By using the attribute argument 'other', the programmer can specify that the type of the argument could be anything. The other attribute argument indicates that a single argument is desired, for multiple arguments the list attribute argument should be used.

Class Name

Any class name can be specified as an argument. If a class name is specified, only arguments of that class, or objects that inherit from that class will be accepted as valid arguments. This being said, the programmer would be wise to specify the lowest (most specific, least abstract) available subclass that can be used by the subroutine as the argument attribute.

Optional o

The lowercase 'o' indicates that any following arguments are considered optional. This can be used in front of any of the actual argument attributes, in fact, it can be used at the start of an attribute argument list to indicate that all of the arguments will be optional to the subroutine (even so, you can still type check them if they are present). Multiple arguments defined this way must be specified positionally to the subroutine, unless the attribute argument 'other' is used ubiquitously. In any case, an argument will be considered required and an exception will be thrown if it is missing unless the 'o' attribute argument precedes it.

EXAMPLES

See SYNOPSIS.

TODO

Make a simple utility which turns the Attribute Enhanced code into comments for production ready code.

Get the stack trace to start from before the method is called (ie take out all of the Attribute::Method::Typeable calls off the top).

And a syntax for alterations (SomeClass|OtherClass) and lists list(Thingy).

AUTHOR

Jeremiah Jordan <jjordan@perlreason.com>

Copyright (c) 2004, Perl Reason, LLC. All Rights Reserved.

This module is free software. It may be used, redistributed and/or modified under the terms of the Perl Artistic License (see http://www.perl.com/perl/misc/Artistic.html)

1 POD Error

The following errors were encountered while parsing the POD:

Around line 669:

=cut found outside a pod block. Skipping to next block.