NAME
Data::Hopen::Scope - a nested key-value store.
SYNOPSIS
A Scope represents a set of data available to operations. It is a key-value store that falls back to an outer Scope
if a requested key isn't found.
This class is the abstract base of Scopes. See Data::Hopen::Scope::Hash for an example of a concrete implementation using a hash under the hood. Different subclasses use different representations. See "FUNCTIONS TO BE OVERRIDDEN IN SUBCLASSES" for more on that topic.
STATIC EXPORTS
FIRST_ONLY
A flag used as a "$set" (q.v.).
ATTRIBUTES
outer
The fallback Scope
for looking up names not found in this Scope
. If non is provided, it is undef
, and no fallback will happen.
local
(Default falsy.) If truthy, do not go past this scope when doing local lookups (see "$levels" below).
name
Not used, but provided so you can use "hnew" in Data::Hopen to make Scopes.
PARAMETERS
The methods generally receive the same parameters. They are as follows.
$name
The name of an item to be looked up. Names must be truthy. That means, among other things, that '0'
is not a valid key.
$set
A Scope can have multiple sets of data. $set
specifies which one to look in.
If specified as a number or a name, look only in that set.
If
'*'
, look in every available set at this level, and return a hashref of{ set_name => value }
. Note that this is not recursive --- it won't collect all instances of the given name from all sets in all the levels. (TODO? change this?)If "FIRST_ONLY", look in only the first set (usually named
0
).If unspecified or undefined, look in every available set at this level, and return the first one found, regardless of which set it comes from.
$levels
How many levels up ("outer") to go when performing an operation. Note: chains more than POSIX::INT_MAX
("LIMITS" in POSIX) Scopes long may fail in unexpected ways, depending on your platform! For 32- or 64-bit platforms, that number is at least 2,000,000,000, so you're probably OK :) .
If numeric and non-negative, go up that many more levels (i.e.,
$levels==0
means only return this scope's local names).If
'local'
, go up until reaching a scope with "local" set. If the current scope has "local" set, don't go up at all.If not provided or not defined, go all the way to the outermost Scope.
METHODS
See also "add", below, which is part of the public API.
find
Find a named data item in the scope and return it. Looks up the scope chain to the outermost scope if necessary. Returns undef on failure. Usage:
$scope->find($name[, $set[, $levels]]);
$scope->find($name[, -set => $set][, -levels => $levels]);
# Alternative using named arguments
Dies if given a falsy name, notably, '0'
.
names
Returns a Set::Scalar of the names of the items available through this Scope, optionally including all its parent Scopes (if any). Usage and example:
my $set = $scope->names([$levels]);
say "Name $_ is available" foreach @$set; # Set::Scalar supports @$set
If no names are available in the given $levels
, returns an empty Set::Scalar
.
TODO? Support a $set
parameter?
as_hashref
Returns a hash of the items available through this Scope, optionally including all its parent Scopes (if any). Usage:
my $hashref = $scope->as_hashref([-levels => $levels][, -deep => $deep])
If $levels
is provided and nonzero, go up that many more levels (i.e., $levels==0
means only return this scope's local names). If $levels
is not provided, go all the way to the outermost Scope.
If $deep
is provided and truthy, make a deep copy of each value (using "clone" in Data::Hopen. Otherwise, just copy.
TODO? Support a $set
parameter?
outerize
Set "outer", and return a scalar that will restore "outer" when it goes out of scope. Usage:
my $saver = $scope->outerize($new_outer);
$new_outer
may be undef
or a valid Scope
.
FUNCTIONS TO BE OVERRIDDEN IN SUBCLASSES
To implement a Scope with a different data-storage model than the hash this class uses, subclass Scope and override these functions. Only "add" is part of the public API.
add
Add key-value pairs to this scope. Returns the scope so you can chain. Example usage:
my $scope = Data::Hopen::Scope->new()->add(foo => 1);
add
is responsible for handling any conflicts that may occur. In this particular implementation, the last-added value for a particular key wins.
TODO add $set
option. TODO? add -deep option?
_names_here
Populates a Set::Scalar with the names of the items stored in this Scope, but not any outer Scope. Called as:
$scope->_names_here($retval[, $set])
$retval
is the Set::Scalar
instance. $set
is as defined above.
No return value.
_find_here
Looks for a given item in this scope, but not any outer scope. Called as:
$scope->_find_here($name[, $set])
Returns the value, or undef
if not found.