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:
- 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:
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:
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
RT: CPAN's request tracker
Search CPAN
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.