| Object-AutoAccessor documentation | Contained in the Object-AutoAccessor distribution. |
Object::AutoAccessor - Accessor class by using AUTOLOAD
use Object::AutoAccessor;
my $struct = {
foo => {
bar => {
baz => 'BUILD OK',
},
},
};
# Now let's easily accomplish it.
my $obj = Object::AutoAccessor->build($struct);
print $obj->foo->bar->baz; # prints 'BUILD OK'
# OK, now reverse it!
$obj->foo->bar->baz('TO HASHREF');
my $hashref = $obj->as_hashref;
print $hashref->{foo}->{bar}->{baz}; # prints 'TO HASHREF';
# Of course, new() can be used.
$obj = Object::AutoAccessor->new();
# setter methods
$obj->foo('bar');
$obj->set_foo('bar');
$obj->param(foo => 'bar');
# getter methods
$obj->foo();
$obj->get_foo();
$obj->param('foo');
# $obj->param() is compatible with HTML::Template->param()
my @keywords = $obj->param();
my $val = $obj->param('hash');
$obj->param(key => 'val');
my $tmpl = HTML::Template->new(..., associate => [$obj], ...);
Object::AutoAccessor is a Accessor class to get/set values by
AUTOLOADed method automatically.
Moreover, param() is compatible with HTML::Template module,
so you can use Object::AutoAccessor object for HTML::Template's
associate option.
Create a new Object::AutoAccessor object. Then you can use several options to control object's behavior.
Create a new object and accessors easily from given hashref structure. Then you can use several options to control object's behavior.
Reconstruct and returns hashref from Object::AutoAccessor object.
Create a new Object::AutoAccessor object as child instance by renew() .
An accessor method for child instance of Object::AutoAccessor object.
If object has child instance then it return TRUE.
Create a new Object::AutoAccessor object to remaining current options.
This method provides an accessor that methodname is same as keyname by using AUTOLOAD mechanism.
# setter methods
$obj->foo('bar');
$obj->set_foo('bar');
$obj->param(foo => 'bar');
# getter methods
$obj->foo();
$obj->get_foo();
$obj->param('foo');
This method is compatible with param() method of HTML::Template module.
# set value
$obj->param(foo => 'bar');
$obj->param(
foo => 'bar',
bar => [qw(1 2 3)],
baz => { one => 1, two => 2, three => 3 }
);
# get value
$obj->param('foo'); # got 'bar'
# get list keys of parameters
@keys = $obj->param();
This is the method to switch behavior of the AUTOLOADed-accessor-method. If set to 0, the object cannot use the AUTOLOADed-accessor-method such as foo() , set_foo() and get_foo() but param() .
$obj->new_node('foo')->param(bar => 'baz');
$obj->autoload(1);
$baz = $obj->foo->bar; # OK
$obj->autoload(0);
$baz = $obj->node('foo')->param('bar'); # OK
$baz = $obj->foo->bar; # NG
Copyright 2005-2006 Michiya Honda, <pia@cpan.org> All rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Object-AutoAccessor documentation | Contained in the Object-AutoAccessor distribution. |
package Object::AutoAccessor; require 5.004; use strict; use Carp; # require 5.004 use vars qw($VERSION $AUTOLOAD); $VERSION = '0.06'; sub new { my $obj = shift; my $class = ref($obj) || $obj; unless (@_ % 2 == 0) { croak "Odd number of argumentes for $class->new()"; } my %args = @_; my $options = { autoload => 1 }; $options->{$_} = $args{$_} for keys %args; bless $options, $class; } sub renew { my $obj = shift; my $class = ref($obj) || $obj; unless (@_ % 2 == 0) { croak "Odd number of argumentes for $class->renew()"; } my %args = @_; if (ref($obj) and UNIVERSAL::isa($obj, __PACKAGE__)) { %args = map { $_ => $obj->{$_} } grep !/^params$/, keys %$obj; } $class->new(%args); } sub renew_node { shift->renew(@_) } sub new_node { my $self = shift; unless (@_) { croak "Not enough arguments for " . ref($self) . "->new_node()"; } my $label = shift; my $child = $self->renew(@_); $self->param($label => $child); $child; } sub node { my $self = shift; unless (@_) { return grep { $self->is_node($_) } keys(%{ $self->{params} }); } my $first = shift; if (@_) { my @children = (); for my $label ($first,@_) { if ($self->is_node($label)) { push(@children, $self->{params}->{$label}); } else { push(@children, undef); } } return wantarray ? @children : [@children]; } else { if ($self->is_node($first)) { return $self->{params}->{$first}; } else { return undef; } } } sub has_node { scalar shift->node() } sub is_node { my $self = shift; unless (@_) { croak "Not enough arguments for " . ref($self) . "->is_node()"; } my $label = shift; return (ref($self->{params}->{$label}) and UNIVERSAL::isa($self->{params}->{$label}, __PACKAGE__)); } sub param { my $self = shift; unless (@_) { return grep { !$self->is_node($_) } keys(%{ $self->{params} }); } my $first = shift; if (@_) { croak "Odd number of argumentes for " . ref($self) . "->param()" unless ((@_ % 2) == 1); my %hash = ($first,@_); for my $key (keys %hash) { my $ref = ( ref $hash{$key} ); if ($ref eq 'HASH') { %{ $self->{params}->{$key} } = %{ $hash{$key} }; } elsif ($ref eq 'ARRAY') { @{ $self->{params}->{$key} } = @{ $hash{$key} }; } elsif ($ref eq 'SCALAR') { $self->{params}->{$key} = $hash{$key}; } else { $self->{params}->{$key} = $hash{$key}; } } if (@_ == 1) { return $self->{params}->{$first}; } } else { if ($self->is_node($first)) { return undef; } my $type = ( ref $self->{params}->{$first} ); if ($type eq 'HASH') { return \%{ $self->{params}->{$first} }; } elsif ($type eq 'ARRAY') { return \@{ $self->{params}->{$first} }; } elsif ($type eq 'SCALAR') { return $self->{params}->{$first}; } else { # CODEREF, IO, GLOB, OBJECT return $self->{params}->{$first}; } } } sub defined { my $self = shift; unless (@_) { croak "Not enough arguments for " . ref($self) . "->defined()"; } my $label = shift; return CORE::defined($self->{params}->{$label}); } sub exists { my $self = shift; unless (@_) { croak "Not enough arguments for " . ref($self) . "->exists()"; } my $label = shift; return CORE::exists($self->{params}->{$label}); } sub delete { my $self = shift; unless (@_) { croak "Not enough arguments for " . ref($self) . "->delete()"; } my $label = shift; return CORE::delete($self->{params}->{$label}); } sub undef { my $self = shift; unless (@_) { croak "Not enough arguments for " . ref($self) . "->undef()"; } my $label = shift; return CORE::undef($self->{params}->{$label}); } sub build { my $obj = shift; my $class = ref($obj) || $obj; unless (@_) { croak "Not enough arguments for " . $class . "->build()"; } my $hashref = shift; unless (UNIVERSAL::isa($hashref, 'HASH')) { croak $class . "->build(): Cannot build: argument is not a HASH reference"; } my $self = $class->new(@_); $self->_build($hashref); $self; } sub _build { my $self = shift; my $struct = shift; for my $key (keys %$struct) { if (UNIVERSAL::isa($struct->{$key}, 'HASH')) { $self->new_node($key)->_build($struct->{$key}); } else { $self->param( $key => $struct->{$key} ); } } } sub as_hashref { my $self = shift; my $hashref = {}; $self->_as_hashref($hashref); } sub _as_hashref { my $self = shift; my $hashref = shift; for my $key (keys %{ $self->{params} }) { if (UNIVERSAL::isa($self->{params}->{$key}, __PACKAGE__)) { $hashref->{$key} = $self->node($key)->_as_hashref($hashref->{$key}); } else { $hashref->{$key} = $self->param($key); } } $hashref; } sub autoload { my $self = shift; $self->{autoload} = shift if @_; $self->{autoload}; } sub AUTOLOAD { my $self = shift; return if $AUTOLOAD =~ /::DESTROY$/; my ($method) = ($AUTOLOAD =~ /.*::(.*?)$/); if ( $self->{autoload} ) { if ( $self->can( $method ) ) { return $self->$method( @_ ); } elsif ($method =~ /^([sg]et_)(.*)$/) { my($prefix, $name) = ($1, $2); if ($prefix eq 'set_') { return $self->param($name => @_); } else { carp "Too many arguments for " . ref($self) . "->get_$name\()" if @_; return $self->param($name); } } else { if ($self->is_node($method)) { if (@_) { undef $self->{params}->{$method}; return $self->param($method => @_); } else { return $self->{params}->{$method}; } } else { return $self->param($method => @_); } } } else { croak(ref($self) . "->$method\() : this method is not implimented"); } return; } sub DESTROY {} 1; __END__