summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2018-05-04 08:49:19 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2018-05-04 08:49:19 +0200
commit783e1a2e76f1bdc90fd72557b9117c4a5101a36f (patch)
tree0bf278403e8107fa86a80f6da392c9e81dedfd0b
parent150fc09a517fa8708690a0f9384f168a124d0a75 (diff)
downloadconfig-ast-783e1a2e76f1bdc90fd72557b9117c4a5101a36f.tar.gz
config-ast-783e1a2e76f1bdc90fd72557b9117c4a5101a36f.tar.bz2
Implement "direct addressing"
An experimental feature that allows the programmer to access configuration settings as if they were methods of the configuration class. E.g. the following setting .foo.bar.baz: 45 can be accessed as $cfg->tree->Foo->Bar->Baz (Keyword names are capitalized to help distinguish them from the regular methods. Also a dash in the setting name should be represented as __ when using it as a method. Thus 'temp-dir' would become Temp__dir). * lib/Config/Tree.pm (subtree): New method. * lib/Config/Tree/Node.pm (is_leaf, is_null): New methods. Overload bool, eq, and "". * lib/Config/Tree/Node/Null.pm: New module. * lib/Config/Tree/Node/Section.pm: Implement AUTOLOAD for accessing settings as methods. * lib/Config/Tree/Node/Value.pm: Implement as_string.
-rw-r--r--lib/Config/Tree.pm5
-rw-r--r--lib/Config/Tree/Node.pm21
-rw-r--r--lib/Config/Tree/Node/Null.pm26
-rw-r--r--lib/Config/Tree/Node/Section.pm20
-rw-r--r--lib/Config/Tree/Node/Value.pm5
-rw-r--r--t/02conf01.t21
6 files changed, 95 insertions, 3 deletions
diff --git a/lib/Config/Tree.pm b/lib/Config/Tree.pm
index e379efa..45b934b 100644
--- a/lib/Config/Tree.pm
+++ b/lib/Config/Tree.pm
@@ -502,6 +502,11 @@ sub tree {
502 return $self->{_tree} //= new Config::Tree::Node::Section(locus => new Config::Tree::Locus); 502 return $self->{_tree} //= new Config::Tree::Node::Section(locus => new Config::Tree::Locus);
503} 503}
504 504
505sub subtree {
506 my $self = shift;
507 return $self->tree->subtree(@_);
508}
509
505sub _get_section_synt { 510sub _get_section_synt {
506 my ($self, $kw, $name) = @_; 511 my ($self, $kw, $name) = @_;
507 512
diff --git a/lib/Config/Tree/Node.pm b/lib/Config/Tree/Node.pm
index 90fb8c4..79e105f 100644
--- a/lib/Config/Tree/Node.pm
+++ b/lib/Config/Tree/Node.pm
@@ -143,6 +143,16 @@ Returns true if node is a leaf node
143 143
144=cut 144=cut
145 145
146sub is_leaf { 0 }
147
148=head2 is_null
149
150Returns true if node is a null node
151
152=cut
153
154sub is_null { 0 }
155
146=head2 is_section() 156=head2 is_section()
147 157
148Returns true if node represents a section. 158Returns true if node represents a section.
@@ -151,7 +161,7 @@ Returns true if node represents a section.
151 161
152sub is_section { ! shift->is_leaf } 162sub is_section { ! shift->is_leaf }
153 163
154=head2 is_section() 164=head2 is_value()
155 165
156Returns true if node represents a value (or statement). 166Returns true if node represents a value (or statement).
157 167
@@ -234,6 +244,15 @@ sub flatten {
234 return &{$sort}(grep { $_->[1]->is_value } @ar); 244 return &{$sort}(grep { $_->[1]->is_value } @ar);
235} 245}
236 246
247use overload
248 bool => sub { 1 },
249 '""' => sub { shift->as_string },
250 eq => sub {
251 my ($self,$other) = @_;
252 return $self->as_string eq $other
253 };
254
255
2371; 2561;
238 257
239 258
diff --git a/lib/Config/Tree/Node/Null.pm b/lib/Config/Tree/Node/Null.pm
new file mode 100644
index 0000000..f03e7a1
--- /dev/null
+++ b/lib/Config/Tree/Node/Null.pm
@@ -0,0 +1,26 @@
1package Config::Tree::Node::Null;
2use parent 'Config::Tree::Node';
3use strict;
4use warnings;
5use Carp;
6
7sub is_null { 1 }
8
9our $AUTOLOAD;
10
11sub AUTOLOAD {
12 my $self = shift;
13 my $key = $AUTOLOAD;
14 $key =~ s/.*:://;
15 if ($key =~ s/^([A-Z])(.*)/\l$1$2/) {
16 return $self;
17 }
18 confess "Can't locate method $AUTOLOAD";
19}
20
21sub as_string { '(null)' }
22
23use overload
24 bool => sub { 0 };
25
261;
diff --git a/lib/Config/Tree/Node/Section.pm b/lib/Config/Tree/Node/Section.pm
index b9d0620..8fec46b 100644
--- a/lib/Config/Tree/Node/Section.pm
+++ b/lib/Config/Tree/Node/Section.pm
@@ -2,6 +2,8 @@ package Config::Tree::Node::Section;
2use parent 'Config::Tree::Node'; 2use parent 'Config::Tree::Node';
3use strict; 3use strict;
4use warnings; 4use warnings;
5use Carp;
6use Config::Tree::Node::Null;
5 7
6sub new { 8sub new {
7 my $class = shift; 9 my $class = shift;
@@ -36,8 +38,6 @@ sub delete {
36 delete $self->{_subtree}{$key}; 38 delete $self->{_subtree}{$key};
37} 39}
38 40
39sub is_leaf { 0 }
40
41sub merge { 41sub merge {
42 my ($self, $other) = @_; 42 my ($self, $other) = @_;
43 while (my ($k, $v) = each %{$other->subtree}) { 43 while (my ($k, $v) = each %{$other->subtree}) {
@@ -57,4 +57,20 @@ sub merge {
57 } 57 }
58} 58}
59 59
60sub as_string { '(section)' }
61
62our $AUTOLOAD;
63
64sub AUTOLOAD {
65 my $self = shift;
66 my $key = $AUTOLOAD;
67 $key =~ s/.*:://;
68 if ($key =~ s/^([A-Z])(.*)/\l$1$2/) {
69 $key =~ s/__/-/g;
70 return $self->subtree($self->{_ci} ? lc($key) : $key)
71 // new Config::Tree::Node::Null;
72 }
73 confess "Can't locate method $AUTOLOAD";
74}
75
601; 761;
diff --git a/lib/Config/Tree/Node/Value.pm b/lib/Config/Tree/Node/Value.pm
index ee14159..c46a139 100644
--- a/lib/Config/Tree/Node/Value.pm
+++ b/lib/Config/Tree/Node/Value.pm
@@ -31,4 +31,9 @@ sub value {
31 31
32sub is_leaf { 1 }; 32sub is_leaf { 1 };
33 33
34sub as_string {
35 my $self = shift;
36 return $self->value
37}
38
341; 391;
diff --git a/t/02conf01.t b/t/02conf01.t
new file mode 100644
index 0000000..b06d0dd
--- /dev/null
+++ b/t/02conf01.t
@@ -0,0 +1,21 @@
1# -*- perl -*-
2use lib qw(t lib);
3use strict;
4use Test;
5use TestConfig;
6use Data::Dumper;
7
8plan(tests => 4);
9
10my $t = new TestConfig(
11 config => [
12 base => '/etc',
13 'file.passwd.mode' => '0644',
14 'file.passwd.root.uid' => 0,
15 'file.passwd.root.dir' => '/root',
16 ]);
17
18ok($t->tree->File->Passwd->Root->Dir);
19ok($t->tree->File->Passwd->Root->Dir,'/root');
20ok($t->tree->File->Base->Name->is_null);
21ok(!$t->tree->File->Base->Name);

Return to:

Send suggestions and report system problems to the System administrator.