Setting arbitrary-depth hash from file

Setting arbitrary-depth hash from file

am 13.04.2008 22:27:18 von Kelly Jones

I have a file with this in it:

a.b = 10
c.d.e = 11
f.g.h.i.j.k = 12

Based on that, I want to set:

$HASH{a}{b} = 10;
$HASH{c}{d}{e} = 11;
$HASH{f}{g}{h}{i}{j}{k} = 12;

This is easy using eval(), but is there a better way?

I realize that entries like "a.b = 10" and "a.b.c = 13" would
conflict, since setting $HASH{a}{b}{c} to 13 automatically sets
$HASH{a}{b} to a hashref. I've confirmed my file has no such conflicts.

This came up when I was looking at the output of snmpwalk. I realize
Perl has lots of modules to handle SNMP, but I was looking to do
something on my own.

--
We're just a Bunch Of Regular Guys, a collective group that's trying
to understand and assimilate technology. We feel that resistance to
new ideas and technology is unwise and ultimately futile.

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Setting arbitrary-depth hash from file

am 13.04.2008 22:36:50 von chas.owens

On Sun, Apr 13, 2008 at 4:27 PM, Kelly Jones
wrote:
> I have a file with this in it:
>
> a.b = 10
> c.d.e = 11
> f.g.h.i.j.k = 12
>
> Based on that, I want to set:
>
> $HASH{a}{b} = 10;
> $HASH{c}{d}{e} = 11;
> $HASH{f}{g}{h}{i}{j}{k} = 12;
>
> This is easy using eval(), but is there a better way?
>
> I realize that entries like "a.b = 10" and "a.b.c = 13" would
> conflict, since setting $HASH{a}{b}{c} to 13 automatically sets
> $HASH{a}{b} to a hashref. I've confirmed my file has no such conflicts.
snip

Something like this should work (warning untested):

my ($path, $val) = $line =~ /^(\S+)\s*=\s*(.*)$/;
my @keys = split /[.]/, $path;
my $ref = %HASH;
$ref = $ref->{$_} = {} for @keys[0 .. $#keys - 1];
$ref->{$keys[-1]} = $val;


--
Chas. Owens
wonkden.net
The most important skill a programmer can have is the ability to read.

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: [PBML] Setting arbitrary-depth hash from file

am 13.04.2008 23:45:18 von merlyn

>>>>> "Kelly" == Kelly Jones writes:

Kelly> I have a file with this in it:
Kelly> a.b = 10
Kelly> c.d.e = 11
Kelly> f.g.h.i.j.k = 12

Kelly> Based on that, I want to set:

Kelly> $HASH{a}{b} = 10;
Kelly> $HASH{c}{d}{e} = 11;
Kelly> $HASH{f}{g}{h}{i}{j}{k} = 12;

Kelly> This is easy using eval(), but is there a better way?

Yes. http://www.perlmonks.org/index.pl?node_id=443584

And if you want better answers to questions, use monks.
Not sure why these mailing lists exist, anyway!

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095

Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: [PBML] Setting arbitrary-depth hash from file

am 14.04.2008 03:31:00 von Richard Lee

Randal L. Schwartz wrote:
>>>>>> "Kelly" == Kelly Jones writes:
>>>>>>
>
> Kelly> I have a file with this in it:
> Kelly> a.b = 10
> Kelly> c.d.e = 11
> Kelly> f.g.h.i.j.k = 12
>
> Kelly> Based on that, I want to set:
>
> Kelly> $HASH{a}{b} = 10;
> Kelly> $HASH{c}{d}{e} = 11;
> Kelly> $HASH{f}{g}{h}{i}{j}{k} = 12;
>
> Kelly> This is easy using eval(), but is there a better way?
>
> Yes. http://www.perlmonks.org/index.pl?node_id=443584
>
> And if you want better answers to questions, use monks.
> Not sure why these mailing lists exist, anyway!
>
>
I am still a newbie.. and I used monks for a while. It's extremely
helpful just like this mailing list.
However, I personally prefer mailing list as it's easy for me to follow
my own question and it's bit faster I think.

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: [PBML] Setting arbitrary-depth hash from file

am 14.04.2008 03:36:56 von merlyn

>>>>> "Richard" == Richard Lee writes:

Richard> I am still a newbie.. and I used monks for a while. It's extremely
Richard> helpful just like this mailing list. However, I personally prefer
Richard> mailing list as it's easy for me to follow my own question and it's
Richard> bit faster I think.

I would say that you're not paying attention if you think *this list*
has better answers or is faster. Monks beats any list hands down
for accuracy and speed.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095

Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: [PBML] Setting arbitrary-depth hash from file

am 14.04.2008 04:38:35 von chas.owens

On Sun, Apr 13, 2008 at 5:45 PM, Randal L. Schwartz
wrote:
> >>>>> "Kelly" == Kelly Jones writes:
>
> Kelly> I have a file with this in it:
> Kelly> a.b = 10
> Kelly> c.d.e = 11
> Kelly> f.g.h.i.j.k = 12
>
> Kelly> Based on that, I want to set:
>
> Kelly> $HASH{a}{b} = 10;
> Kelly> $HASH{c}{d}{e} = 11;
> Kelly> $HASH{f}{g}{h}{i}{j}{k} = 12;
>
> Kelly> This is easy using eval(), but is there a better way?
>
> Yes. http://www.perlmonks.org/index.pl?node_id=443584
snip

At least in Perl 5.8.8 the for loop solution is faster (significantly
so for the get case), but the reduce solution is more general. When
only getting values, the reduce method autovivifies keys; this could
cause errors in the program later.

get_for didn't autovivify 42 42
get_pte did autovivify 42 42
get_reduce did autovivify 42 42
set_for 42 42
set_pte 42 42
set_reduce 42 42
Rate set_pte get_pte set_reduce get_reduce set_for get_for
set_pte 196495/s -- -0% -15% -19% -29% -68%
get_pte 197284/s 0% -- -15% -19% -28% -68%
set_reduce 231848/s 18% 18% -- -5% -16% -62%
get_reduce 242811/s 24% 23% 5% -- -12% -60%
set_for 275692/s 40% 40% 19% 14% -- -55%
get_for 607350/s 209% 208% 162% 150% 120% --

#!/usr/bin/perl

use strict;
use warnings;

use List::Util;
use Benchmark;

sub pointer_to_element {
local ($a, $b);
return List::Util::reduce(sub { \($$a->{$b}) }, \shift, @_);
}

my %h;
my %subs = (
set_pte => sub {
my $ref = pointer_to_element(\%h, qw);
return $$ref = 42;
},
get_pte => sub {
my $ref = pointer_to_element(\%h, qw);
return $$ref;
},
set_reduce => sub {
my $ref = List::Util::reduce(sub {\($$a->{$b}) }, \(\%h), qw);
return $$ref = 42;
},
get_reduce => sub {
my $ref = List::Util::reduce(sub {\($$a->{$b}) }, \(\%h), qw);
return $$ref;
},
set_for => sub {
my $ref = \%h;
$ref = $ref->{$_} = {} for qw;
return $ref->{baz} = 42;
},
get_for => sub {
my $ref = \%h;
$ref = $ref->{$_} for qw;
return $ref->{baz};
},
);

for my $sub (sort keys %subs) {
print "$sub ";
%h = ();
if ($sub =~ /^get/) {
my $val = $subs{$sub}->();
print exists $h{foo}{bar}{baz} ? "did " : "didn't ", "autovivify ";
$h{foo}{bar}{baz} = 42
}
$subs{$sub}->();
print $subs{$sub}->(), " $h{foo}{bar}{baz}\n";
}

Benchmark::cmpthese(-1, \%subs);

snip
> And if you want better answers to questions, use monks.
> Not sure why these mailing lists exist, anyway!
snip

Well, this mailing list exists specifically because all of the
alternatives (Perl Monks, c.l.p.m, c.l.p, etc.) were/are seen as being
hostile to new users. I admit that this list has started to
degenerate (and I am just as guilty as anyone else). Perhaps it is
time to start sending out the FAQ again (I have been meaning to, but
Real Life(tm) interfered). If anyone has any updates for the FAQ, let
me know.

--
Chas. Owens
wonkden.net
The most important skill a programmer can have is the ability to read.

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: [PBML] Setting arbitrary-depth hash from file

am 14.04.2008 13:19:08 von merlyn

>>>>> "(Randal" == (Randal L Schwartz) writes:

(Randal> I would say that you're not paying attention if you think *this list*
(Randal> has better answers or is faster. Monks beats any list hands down
(Randal> for accuracy and speed.

Ouch. I didn't realize you had crossmailed this to three separate lists.
I was complaining only about the poor answers on the Yahoo lists.

beginners@perl.org is a high-quality list.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095

Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/