NAME
Class::HPLOO - Easier way to declare classes on Perl, based in the popular class {...} style and ePod.
DESCRIPTION
This is the implemantation of OO-Classes for HPL. This brings an easy way to create PM classes, but with HPL resources/style.
USAGE
use Class::HPLOO ;
class Foo extends Bar , Baz {
use LWP::Simple qw(get) ; ## import the method get() to this package.
attr ( array foo_list , int age , string name , foo ) ## define attributes.
vars ($GLOBAL_VAR) ; ## same as: use vars qw($GLOBAL_VAR);
my ($local_var) ;
## constructor/initializer:
sub Foo {
$this->{attr} = $_[0] ;
}
## methods with input variables declared:
sub get_pages ($base , \@pages , \%options) {
my @htmls ;
if ( $options{proxy} ) { ... }
foreach my $pages_i ( @pages ) {
my $url = "$base/$pages_i" ;
my $html = get($url) ;
push(@htmls , $html) ;
$this->cache($url , $html) ;
}
return @htmls ;
}
## methos like a normal Perl sub:
sub cache {
my ( $url , $html ) = @_ ;
$this->{CACHE}{$url} = $html ;
}
sub attributes_example {
$this->set_foo_list(qw(a b c d e f)) ;
my @l = $this->get_foo_list ;
$this->set_age(30) ;
$this->set_name("Joe") ;
$this->set_foo( time() ) ;
print "NAME: ". $this->get_name ."\n" ;
print "AGE: ". $this->get_age ."\n" ;
print "FOO: ". $this->get_foo ."\n" ;
}
}
## Example of use of the class:
package main ;
my $foo = new Foo(123) ;
$foo->get_pages('http://www.perlmonks.com/', ['/index.pl','/foo'] , {proxy => 'localhost:8080'}) ;
CONTRUCTOR
The "method" new() is automatically declared by Class::HPLOO, then it calls the initializer that is a method with the name of the class, like Java.
class Foo extends {
## initializer:
sub Foo {
$this->{attr} = $_[0] ;
}
}
** Note that what the initializer returns is ignored! Unless you return a new constructed object or UNDEF. Return UNDEF (a constant of the class) makes the creation of the object return undef.
DESTRUCTOR
Use DESTROY() like a normal Perl package.
Class VERSION
From Class::HPLOO 0.12, you can define the class version in it's declaration:
class Foo [0.01] extends bar , baz {
...
}
This is just a replacement of the original Perl syntax:
use vars qw($VERSION) ;
$VERSION = '0.01' ;
ATTRIBUTES , GLOBAL VARS & LOCAL VARS
You can use 3 types of definitions for class variables:
ATTRIBUTES
The main difference of an attribute of normal Perl variables, is the existence of the methods set and get for each attribute/key. Also an attribute can have a type definition and a handler, soo each value can be automatically formatted before be really set.
For better OO and persistence of objects ATTRIBUTES should be the main choice.
To set an attribute you use:
To define:
attr( type name , ref type name , array name , hash name , sub id )
To set:
$this->set_name($val) ;
## or:
$this->{name} = $val ;
To get:
my $foo = $this->get_name ;
## or:
my $foo = $this->{name} ;
The attr() definition has this syntax:
REF? ARRAY?|HASH? TYPE? NAME
- NAME
-
The name of the attribute.
An attribute only can be set by set_name() and get by get_name(). It also has a tied key with it's NAME in the HASH reference of the object.
- TYPE (optional)
-
Tells the type of the attribute. If not defined any will be used as default.
Standart types:
- any
-
Accept any type of value.
- string | str
-
A normal string.
- integer | int
-
An integer that accepts only [0-9] digits.
- floating | float
-
A floating point, with the format /\d+\.\d+/. If /\.\d+$/ doesn't exists '.0' will be added in the end.
- sub
-
Define an attribute as a sub call:
class foo { attr( sub id ) ; sub id() { return 123 ; } } ## call: $foo->id() ; ## or print " $foo->{id} \n" ;
Personalized types:
To create your own type you can use this syntax:
attr( &mytypex foo ) ;
Then you need to create the sub that will handle the type format:
sub mytypex ($value) { $value =~ s/x/y/gi ; ## do some formatting. return $value ; ## return the value }
Note that a type will handle one value/SCALAR per time. Soo, the same type can be used for array attributes or not:
attr( &mytypex foo , array &mytypex list ) ;
Soo, in the definition above, when list is set with some ARRAY, eache element of the array will be past one by one to the &mytypex sub.
- REF (optional)
-
Tells that the value is a reference. Soo, you need to always set it with a reference:
attr( ref foo ) ; ... $this->set_foo( \$var ) ; ## or $this->set_foo( [1 , 2 , 3] ) ;
- ARRAY or HASH (optional)
-
Tells that the value is an array or a hash of some type.
Soo, for this type:
attr( array int ages ) ;
You can set and get without references:
$this->set_ages(20 , 25 , 30 , 'invalid' , 40) ; ... my @ages = $this->get_ages ;
Note that in this example, all the values of the array will be formated to integer. Soo, the value 'invalid' will be set to undef.
The attribute definition was created to handle object databases and the persistence of objects created with Class::HPLOO. Soo, for object persistence you should use only ATTRIBUTES and GLOBAL VARS.
Note that for object persistence, keys sets in the HASH reference of the object, that aren't defined as attributes, own't be saved. Soo, for the attr() definition below, the key foo won't be persistent:
attr( str bar , int baz ) ;
$this->{bar} = 'persistent' ;
$this->{foo} = 'not persistent' ;
GLOBAL VARS
To set a global variable (static variable of a class), you use this syntax:
vars ($foo , @bar , %baz) ;
Actually this is the same to write:
use vars qw($foo @bar %baz) ;
** Note that a global variable is just a normal Perl variable, with a public access in it's package/class.
LOCAL VARS
This are just variables with private access (only accessed by the scope defined with it).
my ($foo , @bar , %baz) ;
** Note that a local variable is just a normal Perl variable accessed only through it's scope.
Persistence with HDB::Object
From Class::HPLOO/0.16 we can use HDB::Object as a base class for persitence.
Example of class built with it:
use Class::HPLOO ;
class User extends HDB::Object {
use HDB::Object ;
attr( user , pass , name , int age ) ;
sub User( $user , $pass , $name , $age ) {
$this->{user} = $user ;
$this->{pass} = $pass ;
$this->{name} = $name ;
$this->{age} = time ;
}
}
When you create the object it will be automatically stored in the HDB database:
my $user = new User('joe' , '123' , 'Joe Smith' , 30) ;
...
$user = undef ; ## Destroy and automatically save (insert into table User).
To load an already stored object you should use the method load():
my $user = load User("user eq 'joe'") ;
$user->{age} = 40 ;
$user = undef ; ## Destroy and automatically save (update col age).
** Note that you don't need to care about the DB, including the creation of the table! Is everything automatic.
METHODS
All the methods of the classes are declared like a normal sub.
You can declare the input variables to receive the arguments of the method:
sub methodx ($arg1 , $arg2 , \@listref , \%hasref , @rest) {
...
}
## Calling:
$foo->methodx(123 , 456 , [0,1,2] , {k1 => 'x'} , 7 , 8 , 9 ) ;
HTML BLOCKS
You can use HTML blocks in the class like in HPL documents:
class Foo {
sub test {
print <% html_test>(123) ;
}
<% html_test($n)
<hr>
NUMBER: $n
<hr>
%>
}
SUB CLASSES
From version 0.04+ you can declare sub-classes:
class foo {
class subfoo { ... }
}
You also can handle the base name of a class adding "." in the begin of the class name:
class foo {
class .in { ... }
}
In the example above, the class name .in will be translated as foo::in.
DUMP
You can dump the generated code:
use Class::HPLOO qw(dump nice) ;
** The nice option just try to make a cleaner code.
BUILD
The script "build-hploo.pl" can be used to convert .hploo files to .pm files.
Soo, you can write a Perl Module with Class::HPLOO and release it as a normal .pm file without need Class::HPLOO installed.
If you have ePod (0.03+) installed you can use ePod to write your documentation. For .hploo files the ePod need to be always after __END__.
Note that ePod accepts POD syntax too, soo you still can use normal POD for documentation.
SEE ALSO
Perl6::Classes, HPL, HDB::Object, HDB.
AUTHOR
Graciliano M. P. <gm@virtuasites.com.br>
I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P
COPYRIGHT
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.