Config...l::Node(3pm)

🌸 NAME 🌸

Config::Model::Node β€” the class that builds the nodes of a configuration tree. This is its perl manual page (that (3pm) bit = User Contributed Perl Documentation, bestie, you're in the right place πŸ’…).


✨ VERSION ✨

version 2.166 🫢


πŸ’« SYNOPSIS πŸ’«

Okay so here's the whole vibe, in code:

use Config::Model;

# define configuration tree object
my $model = Config::Model->new;
$model->create_config_class(
   name              => 'OneConfigClass',
   class_description => "OneConfigClass detailed description",

   element => [ # use array ref to keep element ordering
       X => {
           type       => 'leaf',
           value_type => 'enum',
           choice     => [qw/Av Bv Cv/]
           status     => 'deprecated',
           description => 'A description (can be long)',
           summary     => 'A summary',
       },
       Y => '*X', # same properties as X element
       Z => '*X', # same properties as X element
   ],

   accept => [
       'ip.*' => {
           type       => 'leaf',
           value_type => 'uniline',
           summary    => 'ip address',
       }
   ]
);
my $instance = $model->instance (root_class_name => 'OneConfigClass');
my $root = $instance->config_root ;

# X is not shown below because of its deprecated status
print $root->describe,"\n" ;
# name         value        type         comment
# Y            [undef]      enum         choice: Av Bv Cv
# Z            [undef]      enum         choice: Av Bv Cv

# add some data
$root->load( steps => 'Y=Av' );

# add some accepted element, ipA and ipB are created on the fly
$root->load( steps => q!ipA=192.168.1.0 ipB=192.168.1.1"! );

# show also ip* element created in the last "load" call
print $root->describe,"\n" ;
# name         value        type         comment
# Y            Av           enum         choice: Av Bv Cv
# Z            [undef]      enum         choice: Av Bv Cv
# ipA          192.168.1.0  uniline
# ipB          192.168.1.1  uniline

Like… read those comments in the code, they're literally telling you the whole story πŸ“


πŸ¦‹ DESCRIPTION πŸ¦‹

This class hands you the nodes of a configuration tree. When a node object gets created, it receives a set of rules that defines its properties inside the configuration tree. Rules first, chaos never ✨

Every node holds a set of elements. And an element can contain any of these:

  • A leaf element, implemented with Config::Model::Value. A leaf can be plain (aka a totally unconstrained value) or it can be strongly typed (values get checked against a set of rules) πŸ’…
  • Another node.
  • A collection of items: a list element, implemented with Config::Model::ListId. Each item can be another node or a leaf.
  • A collection of identified items: a hash element, implemented with Config::Model::HashId. Each item can also be another node or a leaf.

πŸ’… CONFIGURATION CLASS DECLARATION πŸ’…

A class declaration is made of these parameters, bestie, take notes πŸ“

  • name β€” Mandatory "string" parameter. This config class name can be used by a node element inside another configuration class.
  • class_description β€” Optional "string" parameter. This description gets used when generating user interfaces.
  • class β€” Optional "string" that lets you specify a Perl class to override the default implementation (Config::Model::Node). That Perl class must inherit Config::Model::Node. Use with care, fr fr.
  • copyright β€” Optional array of "strings".
  • license β€” Optional string.
  • element β€” Mandatory "array ref" of elements of the configuration class:
element => [ foo => { type = 'leaf', ... },
             bar => { type = 'leaf', ... }
           ]

See below for details on element declaration πŸ‘‡

  • gist β€” A string used to construct a summary of the content of a node. This parameter is used by the user interface to show users the gist of the content of this node. This parameter has no other effect. This string may contain element values in the form "{foo} and @{a_hash_or_list}". When constructing the gist, "{foo}" is replaced by the value of element "foo", and "@{a_hash_of_list}" is replaced by the number of elements of the hash or list element.

Resulting gist is trimmed of extra spaces βœ‚οΈ

  • rw_config β€” Parameter used to load configuration data on demand. See Config::Model::BackendMgr for details.
  • config_dir β€” Configuration directory. See Config::Model::BackendMgr for details.
  • accept β€” Optional list of criteria (i.e. a regular expression to match) to accept unknown elements. Each criteria has a list of specification that enable Config::Model to create a model snippet for the unknown element.

Example:

accept => [
   'list.*' => {
       type  => 'list',
       cargo => {
           type       => 'leaf',
           value_type => 'string',
       },
   },
   'str.*' => {
       type       => 'leaf',
       value_type => 'uniline'
   },
 ]

All "element" parameters can be used when specifying accepted elements.

If Text::Levenshtein::Damerau module is installed, a warning is issued if an accepted element is too close to an existing element πŸ‘€

The parameter "accept_after" lets you specify where to insert the accepted element. This does not change much the behavior of the tree, but it helps generate a more usable user interface.

Example:

element => [
   'Bug' => { type => 'leaf', value_type => 'uniline' } ,
]
accept => [
   'Bug-.*' =>  {
        value_type => 'uniline',
        type => 'leaf'
        accept_after => 'Bug' ,
   }
]

The model snippet above ensures that "Bug-Debian" is shown right after "bug" πŸ›βœ¨


πŸŽ€ ELEMENT DECLARATION πŸŽ€

🌟 Element type 🌟

Each element is declared with an array ref that contains all the necessary info:

element => [
             foo => { ... }
           ]

The most important information from this hash ref is the mandatory type parameter. The type can be:

  • "node" β€” The element is a node of a tree instantiated from a configuration class (declared with "create_config_class( ... )" in Config::Model). See "Node element".
  • "warped_node" β€” The element is a node whose properties (mostly "config_class_name") can be changed (warped) according to the values of one or more leaf elements in the configuration tree. See Config::Model::WarpedNode for details.
  • "leaf" β€” The element is a scalar value. See "Leaf element".
  • "hash" β€” The element is a collection of nodes or values (default). Each element of this collection is identified by a string (just like a regular hash, except that you can set up constraint of the keys). See "Hash element".
  • "list" β€” The element is a collection of nodes or values (default). Each element of this collection is identified by an integer (just like a regular perl array, except that you can set up constraint of the keys). See "List element".
  • "check_list" β€” The element is a collection of values which are unique in the check_list. See CheckList.

Other element properties are:

  • "class" β€” Override the default class for leaf, list and hash elements. The override class must inherit Config::Model::Value for a leaf element, Config::Model::HashId for a hash element and Config::Model::ListId for a list element.
  • level β€” Level is used to set how configuration data is presented to the user in the GUI. Possible level values are "important", "normal" or "hidden".

<Important> elements are shown to the user no matter what. "hidden" elements are, well, hidden πŸ™ˆ The mechanism used to show them is explained with the warp notion (see "Warp: dynamic value configuration" in Config::Model::Value for details).

  • status β€” Possible values are "obsolete", "deprecated" or "standard" (default).
Using a deprecated element issues a warning ⚠️ Using an obsolete element raises an exception (see Config::Model::Exception).
  • summary β€” Summry of the element. This may be used when generating user interfaces. (yes bestie, that typo is canon, we don't fix it πŸ’€)
  • description β€” Long description of the element. This descriptions is used when generating user interfaces.

🧩 Node element 🧩

When declaring a "node" element, you must also provide a "config_class_name" parameter. For instance:

$model ->create_config_class
  (
  name => "ClassWithOneNode",
  element => [
               the_node => {
                             type => 'node',
                             config_class_name => 'AnotherClass',
                           },
             ]
  ) ;

πŸƒ Leaf element πŸƒ

When declaring a "leaf" element, you must also provide a "value_type" parameter. See Config::Model::Value for more details.

#️⃣ Hash element #️⃣

When declaring a "hash" element, you must also provide a "index_type" parameter.

You can also provide a "cargo_type" parameter set to "node" or "leaf" (default).

See Config::Model::HashId and Config::Model::AnyId for more details.

πŸ“œ List element πŸ“œ

You can also provide a "cargo_type" parameter set to "node" or "leaf" (default).

See Config::Model::ListId and Config::Model::AnyId for more details.

♻️ Declaration re-use ♻️

Element names can be aliases to save typing:

element => [
  foo => { type = 'leaf', ... },
  bar => '*foo'
]

Since each element probably has a different purpose, their description can be declared outside of the element list using aliases:

element => [
  foo => { type = 'leaf', ... },
  bar => '*foo',
],
description => {
  foo => 'foo description'
  bar => 'bar description'
}

The element properties "summary" and "warp" can also be aliased πŸ”

"status" and "level" can be factorized using a different mechanism:

element => [
  foo => { type = 'leaf', ... },
  bar => '*foo',
  baz => '*foo',
],

status => { deprecated => ['bar']}
level => { important => ['foo','baz']}

🧚 CONSTRUCTOR 🧚

The "new" constructor accepts the following parameters:

  • config_file β€” Specify configuration file to be used by backend. This parameter may override a file declared in the model. Note that this parameter is not propagated in children nodes. 🫢

okay that's part one, stay tuned bestie, there's more πŸ’œ

πŸ” Introspection methods πŸ”

ok so these are the little "wait, who are you tho" methods, they just tell you stuff about the node bestie πŸ’…

  • name β€” hands you back where the node lives, or its config class name if it's the root node πŸ‘‘
  • get_type β€” returns "node". that's it. that's the whole vibe πŸŽ€
  • config_model β€” gives you the entire configuration model, like the whole Config::Model object, the full slay ✨
  • model β€” gives you just this node's configuration model, as a data structure 🌸
  • config_class_name β€” returns the configuration class name of this node πŸ¦‹
  • instance β€” returns the instance object that contains this node. she's inherited from Config::Model::AnyThing πŸ’–
  • has_element β€” arguments: ( name => element_name, [ type => searched_type ], [ autoadd => 1 ] )

returns 1 if the class model has that element declared πŸ’―

also returns 1 if autoadd is 1 (which it is by default, iykyk) and the element name gets matched by the optional accept model parameter πŸ‘€

if type is specified, the element name also has to match the type. no exceptions bestie ⭐

  • find_element β€” parameters: ( element_name , [ case => any ])

returns $name if the class model has the element declared, or if the element name is matched by that optional accept parameter 🌈

if case is set to any, then has_element returns the element name that matches the passed name in a case-insensitive way (so she's not being picky about caps, we love that) πŸ™ˆ

returns empty if nothing matches. rip 🫢

  • model_searcher β€” returns an object whose whole job is searching for an element in the configuration model πŸ”Ž

specifically it returns a Config::Model::SearchElement object. go read Config::Model::SearchElement if you want the details on how to actually run a search πŸ“–

this one is inherited from Config::Model::AnyThing πŸ’œ

  • element_model β€” parameters: ( element_name )

returns the model of the element πŸŽ€

  • element_type β€” parameters: ( element_name )

returns the type of the element (think leaf, hash, list, checklist or node). it also returns the type of a potentially accepted element ✨

heads up: this one dies if the element isn't known or can't be accepted πŸ’€ not a soft lil error, a full death.
  • element_name β€” returns the element name that contains this object. inherited from Config::Model::AnyThing πŸ¦‹
  • index_value β€” see index_value() in Config::Model::AnyThing πŸ‘‘
  • parent β€” see parent in Config::Model::AnyThing πŸ‘‘
  • root β€” see root in Config::Model::AnyThing πŸ‘‘
  • location β€” see location in Config::Model::AnyThing πŸ‘‘
  • backend_support_annotation β€” returns 1 if at least one of the backends attached to self or to a parent node supports reading and writing annotations (aka comments, the little side notes bestie) in the configuration file πŸ“

πŸŽ€ Element property management πŸŽ€

  • get_element_names β€” returns all the available element names, including the ones that were accepted πŸ’…

optional parameters are:

  • all: Boolean. when you set it, it returns all element names, even the hidden ones, and it does not trigger the warp mechanism. defaults to 0. you should set this to 1 when you need this method to read configuration data from a backend πŸ‘€
  • type: returns only elements of the requested type (like "list", "hash", "leaf", ...). by default it returns elements of any type 🌈
  • cargo_type: returns only hash or list elements that contain the requested cargo type. like, if get_element_names gets called with cargo_type => 'leaf', then get_element_names returns hash or list elements that contain a leaf object πŸ“
  • check: "yes", "no" or "skip" ⭐

type and cargo_type can be specified together! and then you get parameters that satisfy both conditions. so with type =>'hash', cargo_type => 'leaf', you only get hash elements that contain leaf objects. both, or nothing 😀

returns a list in array context, and a string (like "join(' ',@array)") in scalar context πŸ“š

  • children β€” exactly like get_element_names but with no parameters. returns the list of elements. this method is polymorphic for all the non-leaf objects of the configuration tree 🌳
  • next_element β€” this is your lil iterator through a node's elements. mandatory parameter is name. optional parameter: status πŸ”

returns the next element name for that status (default is "normal"). returns undef if there's no next element available 🫢

  • previous_element β€” parameters: ( name => element_name )

also a way to iterate through the elements of a node πŸ”

returns the previous element name. returns undef if there's no previous element available πŸ™ˆ

  • get_element_property β€” parameters: ( element => ..., property => ... )

retrieves a property of an element πŸ’…

like, for a model:

element    => [ X => { ... } ]
status     => { X => 'deprecated' }

this call:

$node->get_element_property ( element => 'X', property => 'status' )

returns "deprecated" 🎯

  • set_element_property β€” parameters: ( element => ..., property => ... )

sets a property of an element ✍️

  • reset_element_property β€” parameters: ( element => ... )

resets a property of an element back according to the original model. factory reset energy πŸ”„


πŸ’œ Information management πŸ’œ

  • fetch_element β€” arguments: ( name => .. , [ check => ..], [ autoadd => 1 ] )

fetches and returns an element from a node if the class model has that element declared πŸ’–

it'll also fetch and return an element from a node if autoadd is 1 (default, bestie) and the element name gets matched by the optional accept model parameter ✨

check can be set to "yes", "no" or "skip". when check is "no" or "skip", this method returns undef when the element is unknown, or 0 if the element isn't available (i.e. it's hidden) πŸ‘€

by default, "accepted" elements get automatically created. set autoadd to 0 when you do not want that behavior, because sometimes you do not want the surprise 🚫

  • fetch_element_value β€” parameters: ( name => ... [ check => ...] )

fetches and returns the value of a leaf element from a node πŸƒ

  • fetch_gist β€” returns the gist of the node. see the description of the gist parameter above πŸ“
  • store_element_value β€” parameters: ( name, value )

stores a value in a leaf element from a node πŸ’Ύ

can be invoked with named parameters (name, value, check). like:

( name => 'foo', value => 'bar', check => 'skip' )
  • is_element_available β€” parameters: ( name => ..., )

returns 1 if the element name is available and it's not "hidden". returns 0 otherwise πŸ™ˆ

and as a syntactic sugar, you can call this method with just one parameter:

is_element_available( 'element_name' ) ;
  • accept_element β€” parameters: ( name )

checks and returns the appropriate model of an acceptable element (meaning it's declared as a model "element" or it's part of an "accept" declaration) πŸ’…

returns undef if the element can't be accepted. it's giving rejection 😭

  • accept_regexp β€” parameters: ( name )

returns the list of regular expressions used to check for acceptable parameters. super handy for diagnostics πŸ”Ž

  • element_exists β€” parameters: ( element_name )

returns 1 if the element is known in the model βœ…

  • is_element_defined β€” parameters: ( element_name )

returns 1 if the element is defined βœ…

  • grab β€” see grab in Config::Model::Role::Grab 🀲
  • grab_value β€” see grab_value in Config::Model::Role::Grab 🀲
  • grab_root β€” see grab_root in Config::Model::Role::Grab 🌳
  • get β€” parameters: ( path => ..., mode => ... , check => ... , get_obj => 1|0, autoadd => 1|0)

gets a value from a directory-like path πŸ“‚ if get_obj is 1, then get returns a leaf object instead of returning its value. surprise, you get the whole object πŸ‘‘

  • set β€” parameters: ( path , value)

sets a value from a directory-like path ✍️


βœ… Validation βœ…

  • deep_check β€” scans the tree and does a deep check on all the elements that support this. currently only hash or list elements have this feature πŸ”¬

πŸ’… data modification πŸ’…

  • migrate β€” forces a read of the configuration and performs all the changes related to deprecated elements or values. returns 1 if data needs to be saved πŸ’Ύ
  • apply_fixes β€” parameters: [ Perl regexp filter ]

scans the tree starting from this node and applies the fixes attached to warning specifications. see warn_if_match or warn_unless_match in Config::Model::Value πŸ”§

returns $self since v2.151 ✨

the optional filter parameter limits the fixes to elements whose name matches the filter 🎯

for example, using the dpkg-control model, the following call applies fixes on Build-Depends and Build-Depend-Indep elements:

apply_fixes('Build')
  • load β€” parameters: ( steps => string [ ... ])

loads configuration data from the string into the node and its siblings πŸ“₯

this string follows the syntax defined in Config::Model::Loader. see load in Config::Model::Loader for the details on parameters πŸ“–

this method can also be called with a single parameter:

$node->load("some data:to be=loaded");
  • load_data β€” parameters: ( data => hash_ref, [ check => $check, ... ])

loads configuration data with a hash ref 🧺 the hash ref key has to match the available elements of the node (or an accepted element). and the hash ref structure has to match the structure of the configuration model, no free-styling πŸ”’

use check => skip to make data loading more tolerant: bad data just gets discarded πŸ—‘οΈ

load_data can also be called with a single hash ref parameter 🫢

returns 1 if some data were saved (instead of being skipped) πŸ’―

  • needs_save β€” returns 1 if one of the elements in the node's sub-tree has been modified πŸ‘€

🌈 Serialization 🌈

  • dump_tree β€” dumps the configuration data of the node and its siblings into a string πŸ“œ see dump_tree in Config::Model::Dumper for the parameter details πŸ‘‘

this string follows the syntax defined in Config::Model::Loader. and the string that dump_tree produces can be passed right into load πŸ” it's giving round trip ✨

  • describe β€” parameters: ( [ element => ... ] )

provides a description of the node elements, or of just one element πŸ“

  • report β€” provides a text report on the content of the configuration below this node πŸ“Š
  • audit β€” provides a text audit on the content of the configuration below this node πŸ” this audit only shows values that differ from their default value. so if you see it, it's different, periodt πŸ‘‘ (a sibling for fix data edition)
  • copy_from β€” parameters: ( from => another_node_object, [ check => ... ] )

copies configuration data from another node into this node and its siblings πŸ“‹ the copy can be done in a tolerant mode where invalid data gets discarded with check => skip. and you can call this method with just a single argument: copy_from($another_node) πŸ’–

πŸ’… Help management πŸ’…


πŸ” get_help

Parameters: ( [ [ description | summary ] => element_name ] )

Okay bestie, here's the tea β˜• β€” this one's your lil helper for pulling up help text:

  • Call it with no element at all and you get back the description of the whole class. That's the stuff hiding in the class_description attribute of a node declaration. πŸ‘‘
  • Call it with an element name and it hands you that element's description β€” which lives in the description attribute of a node declaration. Simple as.
  • Call it with 2 arguments and it'll give you back either the summary or the description of that element, whichever one you asked for. ✨

And if there's genuinely no description to be found? You get back an empty string. No drama, no error, just silence. πŸ’€


πŸ“‹ get_info

Returns a list of information related to the node. If you want the full deets, go peek at get_info over in Config::Model::Value β€” it explains way more. 🫢


🌳 tree_searcher

Parameters: ( type => ... )

Returns an object that's able to search the configuration tree. The parameters are:

  • type β€” where you want the search to happen. Your options are element, value, key, summary, description, help or all. Pick your fighter. πŸ’–

Then β€” and this is the important bit β€” you gotta call the search method on the object that tree_searcher just handed you. It doesn't search on its own, she needs a little encouragement. πŸ™ˆ

Returns a Config::Model::TreeSearcher object. Slay.


πŸ¦‹ Lazy load of node data

So here's the thing β€” as configuration models keep getting bigger and bigger, loading a whole tree takes longer and longer. 😭 The Config::Model::BackendMgr class is the iconic solution: it gives you a way to load the configuration information only when it's actually needed. Main character energy, honestly. Efficiency queen. πŸ‘‘


πŸ‘‘ AUTHOR πŸ‘‘

Dominique Dumont, (ddumont at cpan dot org)


πŸŽ€ SEE ALSO πŸŽ€

  • Config::Model
  • Config::Model::Instance
  • Config::Model::HashId
  • Config::Model::ListId
  • Config::Model::CheckList
  • Config::Model::WarpedNode
  • Config::Model::Value

🫢 AUTHOR 🫢

Dominique Dumont


This software is Copyright (c) 2005-2022 by Dominique Dumont.

This is free software, licensed under:

The GNU Lesser General Public License, Version 2.1, February 1999

And that's a wrap on Config::Model::Node, bestie!! 🌈 This page shipped with perl v5.42.3, dated 2026-07-23, and it lives at Config::Model::Node(3pm). Go forth and configure responsibly πŸ’…βœ¨πŸ“

πŸ“¦ where this page comes from