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

NAME

Fukurama::Class - Pragma to extend the Perl-OO (in native Perl)

VERSION

Version 0.032 (beta)

SYNOPSIS

 package MyClass;
 use Fukurama::Class(
        extends         => 'MyParent::Class',
        implements      => ['MyFirst::Interface', 'MySecond::Interface'],
        abstract        => 1,
        version         => 1.7,
 );
 sub new : Constructor(public|string) {
        my $class = $_[0];
        my $name = $_[1];
        
        bless({ name => $name }, $class);
 }
 sub get_name : Method(public final|string|) {
        my $self = $_[0];
        
        return $self->{'name'};
 }
 1;

EXPORT

METHODS

MODIFY_CODE_ATTRIBUTES, UNIVERSAL::caller, UNIVERSAL::isa

Existing ones will be decorated, not overwritten

CODE ATTRIBUTES

Constructor, Method

CHANGES OF PERL MODULES

UNIVERSAL::isa

This method would be decorated to handle the implemented interfaces.

CORE::GLOBAL::caller

This method would be decorated to hide the check-wrappers for Method and Constructor attributes.

PROVIDED FUNCTIONS

use of strict and warnings by default

use strict and use warnings are activated by default in your class.

package-name check

Your packagename has to be as provided by path and filename to avoid typos.

Abstract classes

Any access to these classes from non-childs would croak at runtime

Multi-inheritation check

Multiple defined methods in multi-inheritations would croak at compiletime

Implementation of interfaces

Not implemented subs would croak at compiletime

Constructor and method signatures

Non-static subs croak at runtime if you call them as static sub

Private subs croak at runtime if you call them from other classes

Protected subs croak at runtime if you call them from outside the inheritation

Final subs croak at compiletime if any child try to overwrite them

Abstract methods croak at compiletime if you doesn't define them in the child class

Abstract methods croak at runtime if you call them

Parameter and return-value check of methods and constructors

Any parameter which isn't equivalent to the signature would croak at runtime

Any return value which isn't equivalent to the signature would croak at runtime

DESCRIPTION

Use this pragma to have more reliability for developing your programs. It will slow down your code a bit but you can disable the whole pragma for production with only one line without any side effect.

PRAGMA-OPTIONS

extends => STRING

Define, from wich class you would inherit. This is only a wrapper for the base pragma. Feel free to use this one or base direct. It's only for the sake of completeness.

implements => ARRAYREF of STRING

A list of interfaces you have to implement. You will not inherit from theese classes even thought UNIVERSAL::isa will say that.

abstract => BOOLEAN

Declare this class as an abstract one.

version => INT

Set the $VERSION variable in your module. Same as you say our $VERSION = INT (at compiletime)

DEFINE SIGNATURES

You can define signatures for constructors and methods. If you overwride some subs from your parent-class, you have to use exact the same signature ore an extended version (see "EXTEND SIGNATURES"). Otherwise it will croak at compiletime.

Constructor signatures
 sub new : Constructor(ACCESS_LEVEL TYPE | PARAMETERS) {

Any constructor is static. But if you call $object->new( ) it will cause no check-error.

The return-value of any constructor has to be a blessed reference which is a member of the actual class.

Method signatures
 sub get : Method(ACCESS_LEVEL IS_STATIC TYPE | RETURN_VALUE | PARAMETERS) {

DECLARATION OPTIONS

ACCESS_LEVEL: ENUM

Can be on of the following. If you overwrite methods, you can't change the access-level in the inheritation tree, because public methods start with no underscore and all other with an underscore. With this caveat and the fact, that there are no real private methods in perl it's more uncomplicated to do so.

public

You can access these sub from anywhere. There are no restrictions.

protected

You can access these sub only from its own package or members of this class (even parents). All calls from outside will croak at runtime.

private

You can access these sub only from its own package. All other calls will croak at runtime.

There are two things to comply the perl-styleguide:

sub _methodname

Any sub with an initial underscore can be protected or private. If you doesn't define the ACCESS_LEVEL, it will be protected by default. If you define this as public it will croak at compiletime.

sub methodname

Any sub with no initial unterscore can be only public. If you doesn't define the ACCESS_LEVEL, it will be public by default. If you define it as protected or private it will croak at compiletime

so you can say:

 sub _methodname : Method(|void|)

and you will get the same as

 sub _methodname : Method(protected|void|)
IS_STATIC: ENUM

Can be...

static

If the sub is static, you can call it direct via CLASSNAME->sub( ) or via object $obj->sub(). A direct call via &sub() will croak at runtime.

If static is not defined, you can only call these sub via $object->sub(). All other accesses will croak at runtime

TYPE: ENUM

Can be one of...

abstract

This sub is abstract. You doesn't have to define any method-body, because this method could be never called. All children of this class have to implement this method with the same or the extended method-signature.

final

This sub is finalized. No child can overwrite an redifine this method. This will croak at compiletime

RETURN_VALUE

The definition of the return value. In this standard definition there is no determination between array and scalar context. If you define void as return value and call it in scalar or array context, there would be no warning.

If there is a difference between array and scalar context, you have to define the array-context return values separate after an @ like

 sub append : Method(public|SCALAR_RETURN @ ARRAY_RETURN|);

Examples:

sub append : Method( public|string| )

returns a string

sub append : Method( public|string, boolean| )

returns a string and a boolean

sub append : Method( public|string[] @ string()| )

returns an arrayref of strings in scalar, and an array of strings in array context

PARAMETERS

The definition, which parameters your sub can take seperated by comma. If there is no parameter you have to define nothing.

Optional parameters can be defined after a semicolon.

Examples:

sub append : Method( public|void| )

Takes no parameters

sub append : Method( public|void|string )

Takes a single string as parameter

sub append : Method( public | void | string[]; scalar, scalar )

Takes an arrayref of strings and two optional scalars as parameters

POSSIBLE PARAMETERS AND RETURN VALUES

The following things you can use for parameters or return values:

void (only for return values)

The sub returns nothing (undef). Only valid for a single return value.

It isn't valid if you try to define a void return value for array-context or any other return value with void. This will croak at compiletime

scalar

Anything what you can put into a scalar variable, i.e. references, strings, objects, undef, etc.

scalarref

A reference to a scalar.

arrayref

A reference to an array.

hashref

A reference to a hash.

typeglobref

A reference to a typeglob

string

A scalar with string content. It behaves like scalar but it can't be undef.

boolean

A scalar which can contain 1 or 0.

int

A scalar which can contain an integer. It can't be undef. If this number is too big and produced an overflow, for exampe a string with a huge number, it will croak at runtime.

float

A scalar which can contain any floatingpoint number. It can't be undef. If the number is too big and produced an overflow it will croak at runtime like in int.

decimal

A scalar which can contain any decimal number. It can't be undef. If the number is too big and produced an overflow it will croak at runtime like in int.

But be aware!

If you use too many digits after the point like 1.000000000000001, perl will cut this down to "1" without any notice if you use it as number direct in your code or if you calculate with it. If you give such a number to a method as string, Fukurama::Class would find fault with "overflow".

class

A string which contain a valid classname, i.e 'UNIVERSAL'. Can't be undef.

object

A scalar which can contain any object.

AnyClassname

If there is no specific declaration for the datatype this would be interpreted as class. The parameter or return value must be an OBJECT and a member of the defined class.

At each of these things you can add trailing [] or () to say, that this is an arrayref or an array or these thing. The () can be used for array-context return values and then it has to be the last or the only return value. It also can be the last parameter/optional parameter.

Attention: you can never add some parameters or return values when you use it!

Example:

int[]

An arrayref that contain only integers

MyClass( )

An array that contain only members of the MyClass-class.

EXTEND SIGNATURES

You can extend signatures by the following ways:

set final

Any Non-final sub can be declared as final to avoid overwriting.

add new, optional parameter

You can add (more) optional parameters. The even defined parameters from the sub you overwrite must be exact the same. To overwrite and extend a method for the example parent:

 package Parent;
 sub get_name : Method(public|string|boolean) {

...you can say:

 package Child;
 sub get_name : Method(public|string|boolean;string) {

...but not:

 package Child;
 sub get_name : Method(public|string|string) {

this will croak at compiletime

LOAD CLASSES AT RUNTIME

If some classes are loaded at runtime there couldn't be checked at compiletime. So these classes are checked at destroy-time (END-block) and you will become a warning about this at runtime when the class is loaded.

DISABLE ALL CHECKS

To speed up your code to use it productive you can say:

no Fukurama::Class('runtime_checks');

This will disable all runtime checks as to callers, parameters and return values. This will speed up your code most.

no Fukurama::Class('checks');

This will disable all checks for runtime as above and for compiletime as to checks of implementations of abstract methods and interfaces, use same or extended signatures for overwritten subs and the package-name checks.

If you say this, only decorations for the methods UNIVERSAL::isa( ) and MODIFY_CODE_ATTRIBUTE( ) (which will be in several classes) would stay. Even warning are disabled, because of the runtime-warning checks.

But the strict would never be disabled.

CUSTOM SETTINGS

You can control the whole behavior of all submodules. Take a look at the specific module documentation.

METHODS

declare( export_to_class:STRING, export_depth:INT ) return:VOID

Helper method to white wrapper or adapter for this class. You can define to which class all functionality would be exported. For the automatic pollution of strict() an warnings() you have to define the caller level, in which this behavior would be exported.

ATTENTION! For automatic export of strict() and warnings() behavior you have to call this method in an import() method at compiletime.

run_check( ) return:VOID

Helper method for static perl (see BUGS). This method check all declarations and implement parameter and return value checker.

unimport( ) return:VOID

Perl-intern method to provide the 'no Fukurama::Class' functionality. See section "DISABLE ALL CHECKS" above.

AUTHOR

Tobias Tacke, <cpan at tobias-tacke.de>

BUGS

This pragma you can only use for non-static perl. Most of the features use the perl-buildin CHECK-block, but mod_perl or fastCGI doesn't support this block.

In mod_perl you can "fake" this, if you say:

 Fukurama::Class->run_check();

in the main-handler method and all is well. All compile-time checks would croak in this line, if there are errors. Not fine but it works.

I still have to discover hov the attributes like "Private" in Catalyst work. There must be a hack :)

Please report any bugs or feature requests to bug-fukurama-class at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Fukurama-Class. I will be notified, and then you'll automatically be notified of any progress on your bug as I make changes.

SUPPORT

You can find the documentation of this module with the perldoc command.

    perldoc Fukurama::Class

You can also look for information at:

ACKNOWLEDGEMENTS

COPYRIGHT & LICENSE

Copyright 2007 Tobias Tacke, all rights reserved.

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