App-Context
view release on metacpan or search on metacpan
lib/App/Reference.pm view on Meta::CPAN
#############################################################################
## $Id: Reference.pm 9683 2007-06-26 15:30:18Z spadkins $
#############################################################################
package App::Reference;
$VERSION = (q$Revision: 9683 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers generated by svn
use strict;
use App;
=head1 NAME
App::Reference - a Perl reference, blessed so it can be accessed with methods
=head1 SYNOPSIS
use App::Reference;
$ref = App::Reference->new();
$ref = App::Reference->new("file" => $file);
print $ref->dump(), "\n"; # use Data::Dumper to spit out the Perl representation
# accessors
$property_value = $ref->get($property_name);
$branch = $ref->get_branch($branch_name,$create_flag); # get hashref
$ref->set($property_name, $property_value);
# on-demand loading helper methods (private methods)
$ref->overlay($ref2); # merge the two structures using overlay rules
$ref->overlay($ref1, $ref2); # merge $ref2 onto $ref1
$ref->graft($branch_name, $ref2); # graft new structure onto branch
=head1 DESCRIPTION
App::Reference is a very thin class which wraps a few simple
methods around a perl reference which may contain a multi-level data
structure.
=cut
#############################################################################
# CLASS
#############################################################################
=head1 Class: App::Reference
* Throws: App::Exception
* Since: 0.01
=head2 Requirements
The App::Reference class satisfies the following requirements.
o Minimum performance penalty to access perl data
o Ability to bless any reference into this class
o Ability to handle ARRAY and HASH references
=cut
#############################################################################
# CONSTRUCTOR METHODS
#############################################################################
=head1 Constructor Methods:
=cut
#############################################################################
# new()
#############################################################################
=head2 new()
This constructor is used to create Reference objects.
Customized behavior for a particular type of Reference
is achieved by overriding the _init() method.
* Signature: $ref = App::Reference->new($array_ref)
* Signature: $ref = App::Reference->new($hash_ref)
* Signature: $ref = App::Reference->new("array",@args)
* Signature: $ref = App::Reference->new(%named)
* Param: $array_ref []
* Param: $hash_ref {}
* Return: $ref App::Reference
* Throws: App::Exception
* Since: 0.01
Sample Usage:
use "App::Reference";
lib/App/Reference.pm view on Meta::CPAN
return(undef);
}
}
else {
$branch = $branch->{$branch_piece};
}
}
$sub_branch_name .= $type if ($type eq ".");
}
return $branch;
}
#############################################################################
# set()
#############################################################################
=head2 set()
* Signature: $ref->get($property_name, $property_value);
* Param: $property_name string
* Param: $property_value string
* Throws: App::Exception
* Since: 0.01
Sample Usage:
$dbi = $ref->get("Repository.default.dbi");
$dbuser = $ref->get("Repository{default}{dbuser}");
$dbpass = $ref->get("Repository.default{dbpass}");
=cut
sub set {
print "set(@_)\n" if ($App::DEBUG);
my ($self, $property_name, $property_value, $ref) = @_;
$ref = $self if (!defined $ref);
my ($branch_name, $attrib, $type, $branch, $cache_ok);
if ($property_name =~ /^(.*)([\.\{\[])([^\.\[\]\{\}]+)([\]\}]?)$/) {
$branch_name = $1;
$type = $2;
$attrib = $3;
$cache_ok = (ref($ref) ne "ARRAY" && $ref eq $self);
$branch = $ref->{_branch}{$branch_name} if ($cache_ok);
$branch = $self->get_branch($1,1,$ref) if (!defined $branch);
}
else {
$branch = $ref;
$attrib = $property_name;
}
if (ref($branch) eq "ARRAY") {
$branch->[$attrib] = $property_value;
}
else {
$branch->{$attrib} = $property_value;
}
}
#############################################################################
# overlay()
#############################################################################
=head2 overlay()
* Signature: $ref->overlay($ref2);
* Signature: $ref->overlay($ref1, $ref2);
* Param: $ref1 {}
* Param: $ref2 {}
* Return: void
* Throws: App::Exception
* Since: 0.01
Sample Usage:
# merge the two config structures using overlay rules
$ref->overlay($ref2);
# merge $ref2 onto $ref1
$ref->overlay($ref1, $ref2);
NOTE: right now, this just copies top-level keys of a hash reference
from one hash to the other.
TODO: needs to nested/recursive overlaying
=cut
sub overlay {
&App::sub_entry if ($App::trace);
my ($self, $ref1, $ref2) = @_;
if (!defined $ref2) {
$ref2 = $ref1;
$ref1 = $self;
}
my $ref1type = ref($ref1);
my $ref2type = ref($ref2);
if ($ref1type eq "" || $ref2type eq "") {
# scalar: nothing to do
}
elsif ($ref1type eq "ARRAY" || $ref2type eq "ARRAY") {
# array: nothing to do
}
else { # assume they are both hashes
foreach my $key (keys %$ref2) {
if (!exists $ref1->{$key}) {
$ref1->{$key} = $ref2->{$key};
}
else {
$ref1type = ref($ref1->{$key});
if ($ref1type && $ref1type ne "ARRAY") {
$ref2type = ref($ref2->{$key});
if ($ref2type && $ref2type ne "ARRAY") {
$self->overlay($ref1->{$key}, $ref2->{$key});
}
}
}
}
}
&App::sub_exit() if ($App::trace);
}
#############################################################################
# graft()
#############################################################################
=head2 graft()
* Signature: $ref->graft($branch_name, $ref2);
* Param: $branch_name string
* Param: $ref2 {}
* Return: void
* Throws: App::Exception
* Since: 0.01
Sample Usage:
# graft new config structure onto branch
$ref->graft($branch_name, $ref2);
=cut
sub graft {
}
#############################################################################
# dump()
#############################################################################
=head2 dump()
* Signature: $perl = $ref->dump();
* Param: void
* Return: $perl text
* Throws: App::Exception
* Since: 0.01
Sample Usage:
$ref = $context->config();
print $ref->dump(), "\n";
=cut
use Data::Dumper;
sub dump {
my ($self, $ref) = @_;
$ref = $self if (!$ref);
my $d = Data::Dumper->new([ $ref ], [ "ref" ]);
$d->Indent(1);
return $d->Dump();
}
( run in 0.999 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )