.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Config::Model::Loader 3pm" .TH Config::Model::Loader 3pm "2019-01-15" "perl v5.28.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Config::Model::Loader \- Load serialized data into config tree .SH "VERSION" .IX Header "VERSION" version 2.133 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Config::Model; \& \& # define configuration tree object \& my $model = Config::Model\->new; \& $model\->create_config_class( \& name => "Foo", \& element => [ \& [qw/foo bar/] => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq \& }, \& ] \& ); \& \& $model \->create_config_class ( \& name => "MyClass", \& \& element => [ \& \& [qw/foo bar/] => { \& type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq \& }, \& hash_of_nodes => { \& type => \*(Aqhash\*(Aq, # hash id \& index_type => \*(Aqstring\*(Aq, \& cargo => { \& type => \*(Aqnode\*(Aq, \& config_class_name => \*(AqFoo\*(Aq \& }, \& }, \& [qw/lista listb/] => { \& type => \*(Aqlist\*(Aq, \& cargo => {type => \*(Aqleaf\*(Aq, \& value_type => \*(Aqstring\*(Aq \& } \& }, \& ], \& ) ; \& \& my $inst = $model\->instance(root_class_name => \*(AqMyClass\*(Aq ); \& \& my $root = $inst\->config_root ; \& \& # put data \& my $steps = \*(Aqfoo=FOO hash_of_nodes:fr foo=bonjour \- \& hash_of_nodes:en foo=hello \& ! lista=foo,bar lista:2=baz \& listb:0=foo listb:1=baz\*(Aq; \& $root\->load( steps => $steps ); \& \& print $root\->describe,"\en" ; \& # name value type comment \& # foo FOO string \& # bar [undef] string \& # hash_of_nodes node hash keys: "en" "fr" \& # lista foo,bar,baz list \& # listb foo,baz list \& \& \& # delete some data \& $root\->load( steps => \*(Aqlista~2\*(Aq ); \& \& print $root\->describe(element => \*(Aqlista\*(Aq),"\en" ; \& # name value type comment \& # lista foo,bar list \& \& # append some data \& $root\->load( steps => q!hash_of_nodes:en foo.=" world"! ); \& \& print $root\->grab(\*(Aqhash_of_nodes:en\*(Aq)\->describe(element => \*(Aqfoo\*(Aq),"\en" ; \& # name value type comment \& # foo "hello world" string .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This module is used directly by Config::Model::Node to load serialized configuration data into the configuration tree. .PP Serialized data can be written by the user or produced by Config::Model::Dumper while dumping data from a configuration tree. .SH "CONSTRUCTOR" .IX Header "CONSTRUCTOR" .SS "new" .IX Subsection "new" The constructor should be used only by Config::Model::Node. .PP Parameters: .IP "start_node" 4 .IX Item "start_node" node ref of the root of the tree (of sub-root) to start the load from. Stored as a weak reference. .SH "load string syntax" .IX Header "load string syntax" The string is made of the following items (also called \f(CW\*(C`actions\*(C'\fR) separated by spaces. These actions can be divided in 4 groups: .IP "\(bu" 4 navigation: moving up and down the configuration tree. .IP "\(bu" 4 list and hash operation: select, add or delete hash or list item (also known as \f(CW\*(C`id\*(C'\fR items) .IP "\(bu" 4 leaf operation: select, modify or delecte leaf value .IP "\(bu" 4 annotation: modify or delete configuration annotation (aka comment) .SS "navigation" .IX Subsection "navigation" .IP "\-" 8 Go up one node .IP "!" 8 Go to the root node of the configuration tree. .IP "xxx" 8 .IX Item "xxx" Go down using \f(CW\*(C`xxx\*(C'\fR element. (For \f(CW\*(C`node\*(C'\fR type element) .IP "/xxx" 8 .IX Item "/xxx" Go up until the element \f(CW\*(C`xxx\*(C'\fR is found. This search can be combined with one of the command specified below, e.g \f(CW\*(C`/a_string="foo bar"\*(C'\fR .SS "list and hash operation" .IX Subsection "list and hash operation" .IP "xxx:yy" 4 .IX Item "xxx:yy" Go down using \f(CW\*(C`xxx\*(C'\fR element and id \f(CW\*(C`yy\*(C'\fR (For \f(CW\*(C`hash\*(C'\fR or \f(CW\*(C`list\*(C'\fR element with \f(CW\*(C`node\*(C'\fR cargo_type). Literal \f(CW\*(C`\en\*(C'\fR are replaced by real \f(CW\*(C`\en\*(C'\fR (\s-1LF\s0 in Unix). .IP "xxx:.foreach_match(yy) or xxx:~yy" 4 .IX Item "xxx:.foreach_match(yy) or xxx:~yy" Go down using \f(CW\*(C`xxx\*(C'\fR element and loop over the ids that match the regex specified by \f(CW\*(C`yy\*(C'\fR. (For \f(CW\*(C`hash\*(C'\fR). .Sp For instance, with \f(CW\*(C`OpenSsh\*(C'\fR model, you could do .Sp .Vb 1 \& Host:~"/.*.debian.org/" user=\*(Aqfoo\-guest\*(Aq .Ve .Sp to set \*(L"foo-user\*(R" users for all your debian accounts. .Sp The leading and trailing '/' may be omitted. Be sure to surround the regexp with double quote if space are embedded in the regex. .Sp Note that the loop ends when the load command goes above the element where the loop is executed. For instance, the instruction below tries to execute \f(CW\*(C`DX=BV\*(C'\fR and \f(CW\*(C`int_v=9\*(C'\fR for all elements of \f(CW\*(C`std_id\*(C'\fR hash: .Sp .Vb 1 \& std_id:~/^\ew+$/ DX=Bv int_v=9 .Ve .Sp In the examples below only \f(CW\*(C`DX=BV\*(C'\fR is executed by the loop: .Sp .Vb 2 \& std_id:~/^\ew+$/ DX=Bv \- int_v=9 \& std_id:~/^\ew+$/ DX=Bv ! int_v=9 .Ve .Sp The loop is done on all elements of the hash when no value is passed after "\f(CW\*(C`:~\*(C'\fR" (mnemonic: an empty regexp matches any value). .IP "xxx:.rm(yy) or xxx:\-yy" 4 .IX Item "xxx:.rm(yy) or xxx:-yy" Delete item referenced by \f(CW\*(C`xxx\*(C'\fR element and id \f(CW\*(C`yy\*(C'\fR. For a list, this is equivalent to \f(CW\*(C`splice xxx,yy,1\*(C'\fR. This command does not go down in the tree (since it has just deleted the element). I.e. a \&'\f(CW\*(C`\-\*(C'\fR' is generally not needed afterwards. .IP "xxx:.rm_value(yy) or xxx:\-=yy" 4 .IX Item "xxx:.rm_value(yy) or xxx:-=yy" Remove the element whose value is \f(CW\*(C`yy\*(C'\fR. For list or hash of leaves. Does not not complain if the value to delete is not found. .IP "xxx:..rm_match(yy) or xxx:\-~/yy/" 4 .IX Item "xxx:..rm_match(yy) or xxx:-~/yy/" Remove the element whose value matches \f(CW\*(C`yy\*(C'\fR. For list or hash of leaves. Does not not complain if no value were deleted. .IP "xxx:.substitute(/yy/zz/) or xxx=~s/yy/zz/" 4 .IX Item "xxx:.substitute(/yy/zz/) or xxx=~s/yy/zz/" Substitute a value with another. Perl switches can be used(e.g. \f(CW\*(C`xxx:=~s/yy/zz/gi\*(C'\fR) .IP "xxx:yy or xxx:.unshift(yy)" 4 .IX Item "xxx:>yy or xxx:.unshift(yy)" Unshift \f(CW\*(C`yy\*(C'\fR value on \f(CW\*(C`xxx\*(C'\fR list .IP "xxx:@ or xxx:.sort" 4 .IX Item "xxx:@ or xxx:.sort" Sort the list .IP "xxx:.insert_at(yy,zz)" 4 .IX Item "xxx:.insert_at(yy,zz)" Insert \f(CW\*(C`zz\*(C'\fR value on \f(CW\*(C`xxx\*(C'\fR list before \fBindex\fR \f(CW\*(C`yy\*(C'\fR. .IP "xxx:.insert_before(yy,zz)" 4 .IX Item "xxx:.insert_before(yy,zz)" Insert \f(CW\*(C`zz\*(C'\fR value on \f(CW\*(C`xxx\*(C'\fR list before \fBvalue\fR \f(CW\*(C`yy\*(C'\fR. .IP "xxx:.insert_before(/yy/,zz)" 4 .IX Item "xxx:.insert_before(/yy/,zz)" Insert \f(CW\*(C`zz\*(C'\fR value on \f(CW\*(C`xxx\*(C'\fR list before \fBvalue\fR matching \f(CW\*(C`yy\*(C'\fR. .IP "xxx:.insort(zz)" 4 .IX Item "xxx:.insort(zz)" Insert \f(CW\*(C`zz\*(C'\fR value on \f(CW\*(C`xxx\*(C'\fR list so that existing alphanumeric order is preserved. .IP "xxx:.insort(zz)" 4 .IX Item "xxx:.insort(zz)" For hash element containing nodes: creates a new hash element with \&\f(CW\*(C`zz\*(C'\fR key on \f(CW\*(C`xxx\*(C'\fR hash so that existing alphanumeric order of keys is preserved. Note that all keys are sorted once this instruction is called. Following instructions are applied on the created element. I.e. putting key order aside, \f(CW\*(C`xxx:.insort(zz)\*(C'\fR has the same effect as \f(CW\*(C`xxx:zz\*(C'\fR instruction. .IP "xxx:.insort(zz,vv)" 4 .IX Item "xxx:.insort(zz,vv)" For hash element containing leaves: creates a new hash element with \&\f(CW\*(C`zz\*(C'\fR key and assing value \f(CW\*(C`vv\*(C'\fR so that existing alphanumeric order of keys is preserved. Note that all keys are sorted once this instruction is called. Putting key order aside, \f(CW\*(C`xxx:.insort(zz,vv)\*(C'\fR has the same effect as \f(CW\*(C`xxx:zz=vv\*(C'\fR instruction. .IP "xxx:=z1,z2,z3" 4 .IX Item "xxx:=z1,z2,z3" Set list element \f(CW\*(C`xxx\*(C'\fR to list \f(CW\*(C`z1,z2,z3\*(C'\fR. Use \f(CW\*(C`,,\*(C'\fR for undef values, and \f(CW""\fR for empty values. .Sp I.e, for a list \f(CW\*(C`(\*(Aqa\*(Aq,undef,\*(Aq\*(Aq,\*(Aqc\*(Aq)\*(C'\fR, use \f(CW\*(C`a,,"",c\*(C'\fR. .IP "xxx:yy=zz" 4 .IX Item "xxx:yy=zz" For \f(CW\*(C`hash\*(C'\fR element containing \f(CW\*(C`leaf\*(C'\fR cargo_type. Set the leaf identified by key \f(CW\*(C`yy\*(C'\fR to value \f(CW\*(C`zz\*(C'\fR. .Sp Using \f(CW\*(C`xxx:~/yy/=zz\*(C'\fR is also possible. .IP "xxx:.copy(yy,zz)" 4 .IX Item "xxx:.copy(yy,zz)" copy item \f(CW\*(C`yy\*(C'\fR in \f(CW\*(C`zz\*(C'\fR (hash or list). .IP "xxx:.clear" 4 .IX Item "xxx:.clear" Clear the hash or list. .SS "leaf operation" .IX Subsection "leaf operation" .IP "xxx=zz" 4 .IX Item "xxx=zz" Set element \f(CW\*(C`xxx\*(C'\fR to value \f(CW\*(C`yy\*(C'\fR. load also accepts to set elements with a quoted string. (For \f(CW\*(C`leaf\*(C'\fR element) Literal \f(CW\*(C`\en\*(C'\fR are replaced by real \f(CW\*(C`\en\*(C'\fR (\s-1LF\s0 in Unix). Literal \f(CW\*(C`\e\e\*(C'\fR are replaced by \f(CW\*(C`\e\*(C'\fR. .Sp For instance \f(CW\*(C`foo="a quoted string"\*(C'\fR or \f(CW\*(C`foo="\e"bar\e" and \e"baz\e""\*(C'\fR. .IP "xxx=~s/foo/bar/" 4 .IX Item "xxx=~s/foo/bar/" Apply the substitution to the value of xxx. \f(CW\*(C`s/foo/bar/\*(C'\fR is the standard Perl \f(CW\*(C`s\*(C'\fR substitution pattern. .Sp Patterns with white spaces must be surrounded by quotes: .Sp .Vb 1 \& xxx=~"s/foo bar/bar baz/" .Ve .Sp Perl pattern modifiers are accepted .Sp .Vb 1 \& xxx=~s/FOO/bar/i .Ve .IP "xxx~" 4 .IX Item "xxx~" Undef element \f(CW\*(C`xxx\*(C'\fR .IP "xxx.=zzz" 4 .IX Item "xxx.=zzz" Appends \f(CW\*(C`zzz\*(C'\fR value to current value (valid for \f(CW\*(C`leaf\*(C'\fR elements). .IP "xxx=.file(yyy)" 4 .IX Item "xxx=.file(yyy)" Store the content of file \f(CW\*(C`yyy\*(C'\fR in element \f(CW\*(C`xxx\*(C'\fR. .Sp Store STDIn in value xxx when \f(CW\*(C`yyy\*(C'\fR is '\-'. .IP "xxx=.env(yyy)" 4 .IX Item "xxx=.env(yyy)" Store the content of environment variable \f(CW\*(C`yyy\*(C'\fR in element \f(CW\*(C`xxx\*(C'\fR. .SS "annotation" .IX Subsection "annotation" .IP "xxx#zzz or xxx:yyy#zzz" 4 .IX Item "xxx#zzz or xxx:yyy#zzz" Element annotation. Can be quoted or not quoted. Note that annotations are always placed at the end of an action item. .Sp I.e. \f(CW\*(C`foo#comment\*(C'\fR, \f(CW\*(C`foo:bar#comment\*(C'\fR or \f(CW\*(C`foo:bar=baz#comment\*(C'\fR are valid. \&\f(CW\*(C`foo#comment:bar\*(C'\fR is \fBnot\fR valid. .SS "Quotes" .IX Subsection "Quotes" You can surround indexes and values with double quotes. E.g.: .PP .Vb 1 \& a_string="\e"foo\e" and \e"bar\e"" .Ve .SH "Examples" .IX Header "Examples" You can use cme to modify configuration with \f(CW\*(C`cme modify\*(C'\fR command. .PP For instance, if Config::Model::Ssh is installed, you can run: .PP .Vb 1 \& cme modify ssh \*(AqControlMaster=auto ControlPath="~/.ssh/master\-%r@%n:%p"\*(Aq .Ve .PP To delete \f(CW\*(C`Host *\*(C'\fR entry: .PP .Vb 1 \& cme modify ssh \*(AqHost:\-"*"\*(Aq .Ve .PP To specify 2 \f(CW\*(C`Host\*(C'\fR with a single command: .PP .Vb 1 \& cme modify ssh \*(AqHost:"foo* bar*" ForwardX11=yes HostName="foo.com" \- Host:baz HostName="baz.com"\*(Aq .Ve .PP Note the '\f(CW\*(C`\-\*(C'\fR' used to go up one node before "\f(CW\*(C`Host:baz\*(C'\fR\*(L". In this case, \*(R"up one node\*(L" leads to the \*(R"root node\*(L", so \*(R"\f(CW\*(C`!\*(C'\fR\*(L" could also be used instead of \*(R"\f(CW\*(C`\-\*(C'\fR": .PP .Vb 1 \& cme modify ssh \*(AqHost:"foo* bar*" ForwardX11=yes HostName="foo.com" ! Host:baz HostName="baz.com"\*(Aq .Ve .PP Let's modify now the host name of using a \f(CW\*(C`.org\*(C'\fR domain instead of \&\f(CW\*(C`.com\*(C'\fR. The \f(CW\*(C`:~\*(C'\fR operator uses a regexp to loop over several Host entries: .PP .Vb 1 \& cme modify ssh \*(AqHost:~/ba[rz]/ HostName=~s/.com$/.org/\*(Aq .Ve .PP Now that ssh config is mucked up with dummy entries, let's clean up: .PP .Vb 1 \& cme modify ssh \*(AqHost:\-"baz" Host:\-"foo* bar*"\*(Aq .Ve .SH "Methods" .IX Header "Methods" .SS "load" .IX Subsection "load" Load data into the node tree (from the node passed with \f(CW\*(C`node\*(C'\fR) and fill values as we go following the instructions passed with \&\f(CW\*(C`steps\*(C'\fR. (\f(CW\*(C`steps\*(C'\fR can also be an array ref). .PP Parameters are: .IP "steps (or step)" 4 .IX Item "steps (or step)" A string or an array ref containing the steps to load. See \&\*(L"load string syntax\*(R" in above for a description of the string. .IP "check" 4 .IX Item "check" Whether to check values while loading. Either \f(CW\*(C`yes\*(C'\fR (default), \f(CW\*(C`no\*(C'\fR or \f(CW\*(C`skip\*(C'\fR. Bad values are discarded when \f(CW\*(C`check\*(C'\fR is set to \f(CW\*(C`skip\*(C'\fR. .IP "caller_is_root" 4 .IX Item "caller_is_root" Change the target of the \f(CW\*(C`!\*(C'\fR command: when set, the \f(CW\*(C`!\*(C'\fR command go to caller node instead of going to root node. (default is false) .SH "AUTHOR" .IX Header "AUTHOR" Dominique Dumont, (ddumont at cpan dot org) .SH "SEE ALSO" .IX Header "SEE ALSO" Config::Model,Config::Model::Node,Config::Model::Dumper .SH "AUTHOR" .IX Header "AUTHOR" Dominique Dumont .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is Copyright (c) 2005\-2018 by Dominique Dumont. .PP This is free software, licensed under: .PP .Vb 1 \& The GNU Lesser General Public License, Version 2.1, February 1999 .Ve