[31972] in Perl-Users-Digest
Perl-Users Digest, Issue: 3236 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Dec 14 14:09:27 2010
Date: Tue, 14 Dec 2010 11:09:10 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Tue, 14 Dec 2010 Volume: 11 Number: 3236
Today's topics:
Re: code review - JSON parsing and data structures <uri@StemSystems.com>
Re: code review - JSON parsing and data structures <nobody@nowhere.net>
Re: code review - JSON parsing and data structures <jwkrahn@example.com>
Re: code review - JSON parsing and data structures <marc.girod@gmail.com>
Re: code review - JSON parsing and data structures <hjp-usenet2@hjp.at>
Re: code review - JSON parsing and data structures <uri@StemSystems.com>
Re: code review - JSON parsing and data structures <tadmc@seesig.invalid>
Re: code review - JSON parsing and data structures <mh+usenetspam1002@zugschl.us>
Re: code review - JSON parsing and data structures <mh+usenetspam1002@zugschl.us>
Re: code review - JSON parsing and data structures <mh+usenetspam1002@zugschl.us>
Re: code review - JSON parsing and data structures <uri@StemSystems.com>
Re: code review - JSON parsing and data structures sln@netherlands.com
Re: code review - JSON parsing and data structures <m@rtij.nl.invlalid>
Re: code review - JSON parsing and data structures <mh+usenetspam1002@zugschl.us>
Re: code review - JSON parsing and data structures <mh+usenetspam1002@zugschl.us>
Re: code review - JSON parsing and data structures <mh+usenetspam1002@zugschl.us>
Re: Regex to match a numerical IP range <tzz@lifelogs.com>
Re: Regex to match a numerical IP range sln@netherlands.com
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Tue, 14 Dec 2010 04:10:43 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <87sjy0sorw.fsf@quad.sysarch.com>
>>>>> "MH" == Marc Haber <mh+usenetspam1002@zugschl.us> writes:
MH> "Uri Guttman" <uri@StemSystems.com> wrote:
>>>>>>> "MH" == Marc Haber <mh+usenetspam1002@zugschl.us> writes:
MH> P.S.: Is there any perl module that will allow easy parsing of
MH> ISC-style config files (inn, bind, dhcp-*)? They are much less clumsy
MH> than JSON and much better to read than XML.
>>
>> there are many perl modules that parse various config file
>> formats. search cpan for them
MH> I didn't find a single one as flexible as ISC-style, neither did my
MH> colleagues (who are a lot more proficient in perl than I am). The only
MH> other is Config::IniFiles, but .ini style files just suck :-)
YAML is decent enough and is a superset to json. it is readable and
there are perl modules.
MH> I claim too much shell programming, where whitespace around an
MH> assignment isn't valid syntax.
lame excuse! you are using a real programming language now! :)
>> then you could see the .= and realize that
>> makes no sense. it works but why append to a my declaration when
>> assignment works too and is simpler?
MH> That's a leftover from an earlier version when I tried concatting
MH> multiple files into a single string for a single decode call (didn't
MH> work, of course).
reading in a file line by line and then concatenating them is very
silly. perl is reading in large chunks of the file, spliting it into
lines and then you join them back. a round trip of do nothing.
also check out File::Slurp for a simpler api and possibly faster.
MH> my $cfg = JSON::XS->new->relaxed->decode( $string );
>>
>> if you are going to parse multiple files, best to create a jason object
>> and reuse it instead of creating a new one each time.
MH> I was afraid to carry over unwanted state from an earlier invocation
MH> of the object's decode method. I'd rather leave this coded
MH> ineffectively to make sure to the reader that the decode calls are
MH> fully independent to each other.
but the options are what you set for this. your choice but it is usually
not needed to rebuild objects like this unless they get truly dirty
after use.
MH> Again, too much shell experience where it makes the code more robust
MH> when variable interpolation is quoted. And I find it kind of
MH> irritating to quote hard-coded keys like $cfg->{"hosts"} but not when
MH> the key is interpolated.
in the shell, vars are expanded into command words separated by
whitespace. in perl string vars are just strings.
MH> Is there a possibility to write %{$cfg->{"hosts"}} any less clumsy?
not if you want the entire hash as one variable.
MH> my ($hostname, $hostvalue ) = each %hosts ) { print "host
MH> $hostname\n";
MH> my %hostdata = %{$hostvalue};
>>
>> why do you copy a hash there?
MH> Frankly, I didn't know. I just changed the syntax until it compiled
MH> and gave the intended output.
that is a bad habit you should break. you should read the useful
perldocs on refs and perl data structures
perldsc, perllol, perlreftut
MH> | my $cfg = JSON::XS->new->relaxed->decode( $string );
MH> |
MH> | if( defined $cfg->{'host'} ) {
MH> | while( my ($hostname, $hostdata) = each %{$cfg->{'host'}} ) {
MH> | $hosts{$hostname} = $hostdata;
MH> | }
MH> | }
MH> |
MH> | if( defined $cfg->{'service'} ) {
MH> | while( my ($servicename, $servicedata) = each %{$cfg->{'service'}} ) {
MH> | $services{$servicename} = $servicedata;
MH> | }
MH> | }
those can be folded into an inner loop keyed on host and service. it is
a good exercise for you.
but why are you just copying a hash from the config data to another
hash? you can take a reference to it and use that. you can directly
refer to the config data. you can do a direct copy of the hash (and not
a loop). you can also assign stuff (full hash copy or ref) to another
hash (keyed by 'host' or 'service'). that is 4 ways to simplify and/or
speedup this section.
MH> |}
MH> |
MH> |while( my ($hostname, $hostdata) = each %hosts ) {
MH> | print "host $hostname\n";
MH> | print "hostcheck $hostdata->{'hostcheck'}\n";
MH> | foreach my $service( @{$hostdata->{'services'}} ) {
MH> | print "service $service\n";
MH> | }
MH> |}
that is a 2 level data tree print. you don't build up two levels in your
above code. you copy into two separate hashes. your dump code should
match the shape of the building code.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: Tue, 14 Dec 2010 10:45:04 +0100
From: Anselmo Canfora <nobody@nowhere.net>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <4d073cd0$0$6839$5fc30a8@news.tiscali.it>
I did not test this code against you example, but it seems you can do
something like this:
use strict;
use JSON #will use automgically load JSON::XS if installed
# your slurp routines here to load data in $cfg
map {
my $node=$cfg->{hosts}->{$_};
print "host $_:\n";
print "$$node{$_}->{hostcheck}\n";
print "$service\n" for $service @{$node->{services}};
print "_________________________\n\n";
} keys %{$cfg->{hosts}};
Il 13/12/2010 22.34, Marc Haber ha scritto:
> Hi,
>
> I have written a small program which reads in configuration files
> written in JSON (using JSON::XS), parses them into an internal data
> structure and allows different files to be used as source for
> different "records", ending up in the same master data structure.
>
> The code writing out the data again will be more complicated in the
> final version, this has just been simplified to check out whether the
> system parses correctly.
>
> Since I am still a little clumsy in handling perl data structures, I'd
> like you people to comment on the code and give hints about how to
> write things any better. If the input file format could be optimized,
> I'm all open for it.
>
> Thanks in advance!
>
> Greetings
> Marc
>
> P.S.: Is there any perl module that will allow easy parsing of
> ISC-style config files (inn, bind, dhcp-*)? They are much less clumsy
> than JSON and much better to read than XML.
>
> code:
> #!/usr/bin/perl -w
>
> use strict;
> use JSON::XS;
> use Path::Class;
>
> my %hosts;
> for my $file ( @ARGV ) {
> print "parsing $file\n";
> my $string.=scalar file("$file")->slurp;
> my $cfg = JSON::XS->new->relaxed->decode( $string );
>
> if( defined $$cfg{"hosts"} ) {
> while( my ($hostname, $hostdata) = each %{$$cfg{"hosts"}} ) {
> $hosts{"$hostname"} = $hostdata; } } } while(
> my ($hostname, $hostvalue ) = each %hosts ) { print "host
> $hostname\n";
> my %hostdata = %{$hostvalue};
> print "hostcheck ". $hostdata{"hostcheck"}. "\n";
> foreach my $service( @{$hostdata{"services"}} ) {
> print "service $service\n";
> }
> }
>
> Input data and sample session:
> |$ cat linux001
> |{
> | "hosts": {
> | "linux001": {
> | "hostcheck": "ping",
> | "services": [ "ping", "ssh", "http", ],
> | }
> | }
> |}
> |$ cat win001
> |{
> | "hosts": {
> | "win001" : {
> | "hostcheck": "ping",
> | "services": [ "ping", "rdp", ],
> | }
> | }
> |}
> |$ ./keks linux001 win001
> |parsing linux001
> |parsing win001
> |host linux001
> |hostcheck ping
> |service ping
> |service ssh
> |service http
> |host win001
> |hostcheck ping
> |service ping
> |service rdp
> |$
------------------------------
Date: Tue, 14 Dec 2010 02:03:22 -0800
From: "John W. Krahn" <jwkrahn@example.com>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <LhHNo.16085$wf4.171@newsfe05.iad>
Marc Haber wrote:
>
> code:
> #!/usr/bin/perl -w
>
> use strict;
> use JSON::XS;
> use Path::Class;
>
> my %hosts;
> for my $file ( @ARGV ) {
> print "parsing $file\n";
> my $string.=scalar file("$file")->slurp;
> my $cfg = JSON::XS->new->relaxed->decode( $string );
Of course this is Perl so you could write that as:
#!/usr/bin/perl -w
use strict;
use JSON::XS;
use Path::Class;
my %hosts;
local $/;
while ( my $string = <> ) {
print "parsing $ARGV\n";
my $cfg = JSON::XS->new->relaxed->decode( $string );
John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein
------------------------------
Date: Tue, 14 Dec 2010 02:41:43 -0800 (PST)
From: Marc Girod <marc.girod@gmail.com>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <11bcf02b-fb0c-43af-b561-275341f3ffc6@29g2000yqq.googlegroups.com>
On Dec 13, 9:51=A0pm, "Uri Guttman" <u...@StemSystems.com> wrote:
> use warnings is better and more modern than -w
Isn't this an FQA, i.e. a Frequently Questioned Answer?
Am I wrong or haven't I read here contradictory yet
expert advices pro and con?
One argument IIRC is that it depends whether you want
or not to be warned about modules used by the script.
Marc
------------------------------
Date: Tue, 14 Dec 2010 12:33:06 +0100
From: "Peter J. Holzer" <hjp-usenet2@hjp.at>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <slrnigelfi.u6a.hjp-usenet2@hrunkner.hjp.at>
On 2010-12-14 09:10, Uri Guttman <uri@StemSystems.com> wrote:
>>>>>> "MH" == Marc Haber <mh+usenetspam1002@zugschl.us> writes:
> MH> That's a leftover from an earlier version when I tried concatting
> MH> multiple files into a single string for a single decode call (didn't
> MH> work, of course).
>
> reading in a file line by line and then concatenating them is very
> silly.
The code was (trimmed to the essential lines):
for my $file ( @ARGV ) {
$string.=scalar file("$file")->slurp;
}
That doesn't look like reading a file line by line and then
concatenating the lines. It looks like slurping each file and
concatenating the files. (Of course it is possible that
Path::Class::File::slurp is implemented stupidly - I haven't checked)
hp
------------------------------
Date: Tue, 14 Dec 2010 08:44:40 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <87ei9ksc3b.fsf@quad.sysarch.com>
>>>>> "PJH" == Peter J Holzer <hjp-usenet2@hjp.at> writes:
PJH> On 2010-12-14 09:10, Uri Guttman <uri@StemSystems.com> wrote:
>>>>>>> "MH" == Marc Haber <mh+usenetspam1002@zugschl.us> writes:
MH> That's a leftover from an earlier version when I tried concatting
MH> multiple files into a single string for a single decode call (didn't
MH> work, of course).
>>
>> reading in a file line by line and then concatenating them is very
>> silly.
PJH> The code was (trimmed to the essential lines):
PJH> for my $file ( @ARGV ) {
PJH> $string.=scalar file("$file")->slurp;
PJH> }
PJH> That doesn't look like reading a file line by line and then
PJH> concatenating the lines. It looks like slurping each file and
PJH> concatenating the files. (Of course it is possible that
PJH> Path::Class::File::slurp is implemented stupidly - I haven't checked)
not a totally stupid implementation but a poor one with a very odd
option:
sub slurp {
my ($self, %args) = @_;
my $iomode = $args{iomode} || 'r';
my $fh = $self->open($iomode) or croak "Can't read $self: $!";
if ($args{chomped} or $args{chomp}) {
chomp( my @data = <$fh> );
return wantarray ? @data : join '', @data;
}
local $/ unless wantarray;
return <$fh>;
}
if you chomp in scalar mode it will return a scalar of the whole file
without newlines (really $/)!! who would want such a scalar??
and the unchomped slurp is using the undef $/ feature which is slower
than File::Slurp.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: Tue, 14 Dec 2010 08:01:17 -0600
From: Tad McClellan <tadmc@seesig.invalid>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <slrnigeut6.fve.tadmc@tadbox.sbcglobal.net>
Marc Haber <mh+usenetspam1002@zugschl.us> wrote:
> And I find it kind of
> irritating to quote hard-coded keys like $cfg->{"hosts"} but not when
> the key is interpolated.
Then don't quote hard-coded keys either!
From the "Scalar value constructors" section in perldata.pod
(emphasis mine):
In fact, an identifier within such curlies is forced to be a string,
as is any simple identifier within a hash subscript. Neither need
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
quoting. Our earlier example, C<$days{'Feb'}> can be written as
C<$days{Feb}> and the quotes will be assumed automatically.
> Is there a possibility to write %{$cfg->{"hosts"}} any less clumsy?
Only by removing the unnecessary quotes:
%{$cfg->{hosts}}
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/"
The above message is a Usenet post.
I don't recall having given anyone permission to use it on a Web site.
------------------------------
Date: Tue, 14 Dec 2010 18:29:15 +0100
From: Marc Haber <mh+usenetspam1002@zugschl.us>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <ie89he$sbt$1@news1.tnib.de>
"Uri Guttman" <uri@StemSystems.com> wrote:
>>>>>> "MH" =3D=3D Marc Haber <mh+usenetspam1002@zugschl.us> writes:
> MH> I didn't find a single one as flexible as ISC-style, neither did =
my
> MH> colleagues (who are a lot more proficient in perl than I am). The =
only
> MH> other is Config::IniFiles, but .ini style files just suck :-)
>
>YAML is decent enough and is a superset to json. it is readable and
>there are perl modules.
I remember that there were reasons to decide against YAML, but I'll
have them reviewed in due time. For the time being, I need to finish
@things and there is no time for adaption before christmas.
> MH> I claim too much shell programming, where whitespace around an
> MH> assignment isn't valid syntax.
>
>lame excuse! you are using a real programming language now! :)
Valid excuse. I'll still be writing a lot of shell code. I've been an
occasional perl programmer for more than a few years, but the majority
of my nifty little tools are still written in shell. This is unlikely
to change, while my perl is in a steady state of improving.
> MH> Is there a possibility to write %{$cfg->{"hosts"}} any less =
clumsy?
>
>not if you want the entire hash as one variable.
ok.
> MH> my ($hostname, $hostvalue ) =3D each %hosts ) { print "host
> MH> $hostname\n";
> MH> my %hostdata =3D %{$hostvalue};
> >>=20
> >> why do you copy a hash there?
>
> MH> Frankly, I didn't know. I just changed the syntax until it =
compiled
> MH> and gave the intended output.
>
>that is a bad habit you should break. you should read the useful
>perldocs on refs and perl data structures
>
>perldsc, perllol, perlreftut
I have read these, and the Camel book, and the Cookbook, and the FAQ
numerous times in the last years, and the notation is still one of
perl's secrets for me. The docs are useful, but if one doesn't grok
them the first three times, reading them a fourth time is unlikely to
help. I'll do so though after christmas.
> MH> | my $cfg =3D JSON::XS->new->relaxed->decode( $string );
> MH> |
> MH> | if( defined $cfg->{'host'} ) {
> MH> | while( my ($hostname, $hostdata) =3D each =
%{$cfg->{'host'}} ) {
> MH> | $hosts{$hostname} =3D $hostdata;
> MH> | }
> MH> | }
> MH> |
> MH> | if( defined $cfg->{'service'} ) {
> MH> | while( my ($servicename, $servicedata) =3D each =
%{$cfg->{'service'}} ) {
> MH> | $services{$servicename} =3D $servicedata;
> MH> | }
> MH> | }
>
>those can be folded into an inner loop keyed on host and service. it is
>a good exercise for you.
Those can be folded into an inner loop keyed on host and service _IF_
this is the final code. It isn't, and the final code will be quite
different for both cases.
The docs say that one should trim down the code to the minimum needed
to outline the issue, which I did.
>but why are you just copying a hash from the config data to another
>hash? you can take a reference to it and use that. you can directly
>refer to the config data. you can do a direct copy of the hash (and not
>a loop). you can also assign stuff (full hash copy or ref) to another
>hash (keyed by 'host' or 'service'). that is 4 ways to simplify and/or
>speedup this section.
Where am I copying the hash? I don't understand.
> MH> |while( my ($hostname, $hostdata) =3D each %hosts ) {
> MH> | print "host $hostname\n";
> MH> | print "hostcheck $hostdata->{'hostcheck'}\n";
> MH> | foreach my $service( @{$hostdata->{'services'}} ) {
> MH> | print "service $service\n";
> MH> | }
> MH> |}
>
>that is a 2 level data tree print. you don't build up two levels in your
>above code.
I do. Things may be easier to understand if one knows how Nagios is
configured. The services hash which is on the same level than the
hosts hash is ignored by the example code (on purpose, for simplicity
of the code).
I seem to have royally failed with simplifying the code.
Greetings
Marc
--=20
-------------------------------------- !! No courtesy copies, please !! =
-----
Marc Haber | " Questions are the | Mailadresse im =
Header
Mannheim, Germany | Beginning of Wisdom " | =
http://www.zugschlus.de/
Nordisch by Nature | Lt. Worf, TNG "Rightful Heir" | Fon: *49 621 =
72739834
------------------------------
Date: Tue, 14 Dec 2010 18:31:42 +0100
From: Marc Haber <mh+usenetspam1002@zugschl.us>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <ie89m6$sc5$1@news1.tnib.de>
"Peter J. Holzer" <hjp-usenet2@hjp.at> wrote:
>The code was (trimmed to the essential lines):
>
>for my $file ( @ARGV ) {
> $string.=3Dscalar file("$file")->slurp;
>}
>
>That doesn't look like reading a file line by line and then
>concatenating the lines. It looks like slurping each file and
>concatenating the files.
Yes, that's what I originally intended. Originally, I wanted to have
different files mixed together. For example, I would have wanted two
input files:
(1)
{
"host": {
"linux001": {
"hostcheck": "ping",
"services": [ "ping", "ssh", "http", ],
}
}
}
(2)
{
"host": {
"mgmt001" : {
"hostcheck": "ping",
"services": [ "ping", "rdp", ],
}
}
}
to end up in the same datastructure as if the input file were
{
"host": {
"linux001": {
"hostcheck": "ping",
"services": [ "ping", "ssh", "http", ],
}
}
"host": {
"mgmt001" : {
"hostcheck": "ping",
"services": [ "ping", "rdp", ],
}
}
}
which is neither valid json nor what I originally meant. I thus
re-redesigned to the current state.
Greetings
Marc
--=20
-------------------------------------- !! No courtesy copies, please !! =
-----
Marc Haber | " Questions are the | Mailadresse im =
Header
Mannheim, Germany | Beginning of Wisdom " | =
http://www.zugschlus.de/
Nordisch by Nature | Lt. Worf, TNG "Rightful Heir" | Fon: *49 621 =
72739834
------------------------------
Date: Tue, 14 Dec 2010 18:39:51 +0100
From: Marc Haber <mh+usenetspam1002@zugschl.us>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <ie8a59$sgr$1@news1.tnib.de>
"John W. Krahn" <jwkrahn@example.com> wrote:
>Marc Haber wrote:
>> code:
>> #!/usr/bin/perl -w
>>
>> use strict;
>> use JSON::XS;
>> use Path::Class;
>>
>> my %hosts;
>> for my $file ( @ARGV ) {
>> print "parsing $file\n";
>> my $string.=3Dscalar file("$file")->slurp;
>> my $cfg =3D JSON::XS->new->relaxed->decode( $string );
>
>Of course this is Perl so you could write that as:
>
>#!/usr/bin/perl -w
>
>use strict;
>use JSON::XS;
>use Path::Class;
>
>my %hosts;
>local $/;
>while ( my $string =3D <> ) {
> print "parsing $ARGV\n";
> my $cfg =3D JSON::XS->new->relaxed->decode( $string );
That's not functionally identical since all input is first catted
together and then parsed as a single JSON input, which is different
from parsing each input file as its own JSON.
Greetings
Marc
--=20
-------------------------------------- !! No courtesy copies, please !! =
-----
Marc Haber | " Questions are the | Mailadresse im =
Header
Mannheim, Germany | Beginning of Wisdom " | =
http://www.zugschlus.de/
Nordisch by Nature | Lt. Worf, TNG "Rightful Heir" | Fon: *49 621 =
72739834
------------------------------
Date: Tue, 14 Dec 2010 12:52:52 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <87k4jcqm17.fsf@quad.sysarch.com>
>>>>> "MH" == Marc Haber <mh+usenetspam1002@zugschl.us> writes:
>> lame excuse! you are using a real programming language now! :)
MH> Valid excuse. I'll still be writing a lot of shell code. I've been an
MH> occasional perl programmer for more than a few years, but the majority
MH> of my nifty little tools are still written in shell. This is unlikely
MH> to change, while my perl is in a steady state of improving.
there is little reason to ever write shell code anymore. anything beyond
a short script that calls a few programs is better and easier in
perl. if you get near shell flow control or string munging, then perl is
the answer. shell sucks for most anything these days no matter what they
add to it.
>> perldsc, perllol, perlreftut
MH> I have read these, and the Camel book, and the Cookbook, and the FAQ
MH> numerous times in the last years, and the notation is still one of
MH> perl's secrets for me. The docs are useful, but if one doesn't grok
MH> them the first three times, reading them a fourth time is unlikely to
MH> help. I'll do so though after christmas.
reading them over and over is the best way to grok them. there are
several tutorial level docs (see perldoc perl for the doc groups). if
you need more, there are several decent perl books for intermediates out
there.
>> those can be folded into an inner loop keyed on host and service. it is
>> a good exercise for you.
MH> Those can be folded into an inner loop keyed on host and service _IF_
MH> this is the final code. It isn't, and the final code will be quite
MH> different for both cases.
still, the driving loops can be folded and a dispatch table can be used
to handle the unique code for each key. duplicate code should be
factored out when possible. it makes for cleaner and easier to manage
code.
>> but why are you just copying a hash from the config data to another
>> hash? you can take a reference to it and use that. you can directly
>> refer to the config data. you can do a direct copy of the hash (and not
>> a loop). you can also assign stuff (full hash copy or ref) to another
>> hash (keyed by 'host' or 'service'). that is 4 ways to simplify and/or
>> speedup this section.
MH> Where am I copying the hash? I don't understand.
in your config processing loops you just seem to copy a config hash.
>> that is a 2 level data tree print. you don't build up two levels in your
>> above code.
MH> I do. Things may be easier to understand if one knows how Nagios is
MH> configured. The services hash which is on the same level than the
MH> hosts hash is ignored by the example code (on purpose, for simplicity
MH> of the code).
MH> I seem to have royally failed with simplifying the code.
not screwed up, over simplified in showing what you are really trying to
do.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: Tue, 14 Dec 2010 09:57:54 -0800
From: sln@netherlands.com
Subject: Re: code review - JSON parsing and data structures
Message-Id: <cq9fg6lp4b0f7s05f89omdu5bma0t7e3q5@4ax.com>
On Tue, 14 Dec 2010 07:28:23 +0100, Marc Haber <mh+usenetspam1002@zugschl.us> wrote:
>"Uri Guttman" <uri@StemSystems.com> wrote:
>>>>>>> "MH" == Marc Haber <mh+usenetspam1002@zugschl.us> writes:
[snip]
>> MH> if( defined $$cfg{"hosts"} ) {
>
>>don't use that style of dereferencing as it is hard to read.
>
>$cfg->{"hosts"}?
Yes, stick with the -> notation and be consistent throughout so at
a later time this variable can be identified.
[snip]
>
>> MH> while( my ($hostname, $hostdata) = each %{$$cfg{"hosts"}} ) {
>> MH> $hosts{"$hostname"} = $hostdata; } } } while(
>>
>>don't quote scalars like that. it isn't needed and could lead to bugs.
[snip]
>
>Is there a possibility to write %{$cfg->{"hosts"}} any less clumsy?
>
$$ is bad style. Its done, but its hard to read and could be read as
a single $ by mistake.
If $cfg is a reference , then
dereferencing it is as a hash is %{$cfg}
and dereferencing a scalar key from it is ${$cfg} {key}
or $cfg-> {key}
To me, these two dereferencing notations to get the key,
are preferrable over $$cfg{key} which could be misread.
Example:
my $cfg = { hosts => { hello1 => ' data' } };
my %cfg = ( hosts => { hello2 => ' data' } );
print %{$$cfg{"hosts"}},"\n";
print %{$cfg{"hosts"}}, "\n";
-sln
------------------------------
Date: Tue, 14 Dec 2010 19:25:48 +0100
From: Martijn Lievaart <m@rtij.nl.invlalid>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <cepkt7-9f7.ln1@news.rtij.nl>
On Tue, 14 Dec 2010 02:41:43 -0800, Marc Girod wrote:
> On Dec 13, 9:51 pm, "Uri Guttman" <u...@StemSystems.com> wrote:
>
>> use warnings is better and more modern than -w
>
> Isn't this an FQA, i.e. a Frequently Questioned Answer? Am I wrong or
> haven't I read here contradictory yet expert advices pro and con?
>
> One argument IIRC is that it depends whether you want or not to be
> warned about modules used by the script.
Yes, but who wants to be warned about third party modules if that module
does not do a "use warnings" itself? (Your own modules should always use
a "use warnings").
The good thing about using -w is that you may get warnings about
questionable code, or when you forgot to use warnings yourself in a
module.
The downside is that either you use -w and don't use use warnings in your
modules, leading to less reusable modules, or you have to remember to use
-w in your program and use warnings in your modules.
So all in all, I say it is better to be consistent and "use warnings"
throughout.
M4
------------------------------
Date: Tue, 14 Dec 2010 20:03:01 +0100
From: Marc Haber <mh+usenetspam1002@zugschl.us>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <ie8f16$ts6$1@news1.tnib.de>
"Uri Guttman" <uri@StemSystems.com> wrote:
>if you chomp in scalar mode it will return a scalar of the whole file
>without newlines (really $/)!! who would want such a scalar??
=46or example, a parser which treats a newline as regular whitespace.
Greetings
Marc
--=20
-------------------------------------- !! No courtesy copies, please !! =
-----
Marc Haber | " Questions are the | Mailadresse im =
Header
Mannheim, Germany | Beginning of Wisdom " | =
http://www.zugschlus.de/
Nordisch by Nature | Lt. Worf, TNG "Rightful Heir" | Fon: *49 621 =
72739834
------------------------------
Date: Tue, 14 Dec 2010 20:03:01 +0100
From: Marc Haber <mh+usenetspam1002@zugschl.us>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <ie8f16$ts6$2@news1.tnib.de>
Tad McClellan <tadmc@seesig.invalid> wrote:
>Marc Haber <mh+usenetspam1002@zugschl.us> wrote:
>> And I find it kind of
>> irritating to quote hard-coded keys like $cfg->{"hosts"} but not when
>> the key is interpolated.
>
>Then don't quote hard-coded keys either!
Didn't that give some bareword diagnostic under use strict, at least
in earlier perl versions? It's fine now, so it's ok.
>> Is there a possibility to write %{$cfg->{"hosts"}} any less clumsy?
>
>Only by removing the unnecessary quotes:
>
> %{$cfg->{hosts}}
That's still as clumsy as a C typecast.
Greetings
Marc
--=20
-------------------------------------- !! No courtesy copies, please !! =
-----
Marc Haber | " Questions are the | Mailadresse im =
Header
Mannheim, Germany | Beginning of Wisdom " | =
http://www.zugschlus.de/
Nordisch by Nature | Lt. Worf, TNG "Rightful Heir" | Fon: *49 621 =
72739834
------------------------------
Date: Tue, 14 Dec 2010 20:03:01 +0100
From: Marc Haber <mh+usenetspam1002@zugschl.us>
Subject: Re: code review - JSON parsing and data structures
Message-Id: <ie8f16$ts6$3@news1.tnib.de>
Anselmo Canfora <nobody@nowhere.net> wrote:
>map {
> my $node=3D$cfg->{hosts}->{$_};
> print "host $_:\n";
> print "$$node{$_}->{hostcheck}\n";
> print "$service\n" for $service @{$node->{services}};
> print "_________________________\n\n";
>} keys %{$cfg->{hosts}};
That's a very perlish solution which is probably harder to read for
the occasional perl programmer, and it will only replace the example
code and not the code which will do further processing of the read
data.
Greetings
Marc
--=20
-------------------------------------- !! No courtesy copies, please !! =
-----
Marc Haber | " Questions are the | Mailadresse im =
Header
Mannheim, Germany | Beginning of Wisdom " | =
http://www.zugschlus.de/
Nordisch by Nature | Lt. Worf, TNG "Rightful Heir" | Fon: *49 621 =
72739834
------------------------------
Date: Tue, 14 Dec 2010 10:20:20 -0600
From: Ted Zlatanov <tzz@lifelogs.com>
Subject: Re: Regex to match a numerical IP range
Message-Id: <87lj3s5nsr.fsf@lifelogs.com>
On Mon, 13 Dec 2010 12:25:51 -0800 sln@netherlands.com wrote:
s> On Mon, 13 Dec 2010 10:51:11 -0600, Ted Zlatanov <tzz@lifelogs.com> wrote:
>> I think Net::Netmask is much better for this task than any custom
>> solution. Have you tried it?
s> Well, I thought it was just a case of knowing the simple ip
s> address without knowing anything about the CIDR network (block).
s> So given a simple quad part notation and range, a simple comparison
s> would be is all thats needed instead of a full blown cisco type thing.
I wouldn't try to write that code myself because the risk of getting it
wrong is too high. It's surprisingly hard to do IP ranges well,
especially if you need fast operations. But it looks so easy, doesn't it...
Ted
------------------------------
Date: Tue, 14 Dec 2010 10:03:31 -0800
From: sln@netherlands.com
Subject: Re: Regex to match a numerical IP range
Message-Id: <18cfg6la3rtipb3rupldisuq44t4bgkbjt@4ax.com>
On Tue, 14 Dec 2010 10:20:20 -0600, Ted Zlatanov <tzz@lifelogs.com> wrote:
>On Mon, 13 Dec 2010 12:25:51 -0800 sln@netherlands.com wrote:
>
>s> On Mon, 13 Dec 2010 10:51:11 -0600, Ted Zlatanov <tzz@lifelogs.com> wrote:
>>> I think Net::Netmask is much better for this task than any custom
>>> solution. Have you tried it?
>
>s> Well, I thought it was just a case of knowing the simple ip
>s> address without knowing anything about the CIDR network (block).
>s> So given a simple quad part notation and range, a simple comparison
>s> would be is all thats needed instead of a full blown cisco type thing.
>
>I wouldn't try to write that code myself because the risk of getting it
>wrong is too high. It's surprisingly hard to do IP ranges well,
>especially if you need fast operations. But it looks so easy, doesn't it...
>
Yup, its like medusa, you can't really look at its face directly lest
one turns into stone..
-sln
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 3236
***************************************