Breaking reference chians

M

Mark Keightley

Hi

I'm currently writing a script to read windows style config files. You
know the sort of file that reads like this

[section name]
key1 = value1
key2 = value2

[another section name]
....

The config is then held in a hash of hashes. The problem I'm having is
getting the hash with the key value pairs stored in the main config
hash. I've written a sub routine that reads the key value pairs and
then returns a reference to this hash. The problem is that because
there is a reference back to this hash, even with it being a local hash
(created with my) to that sub, it never goes out of scope. Hence only
the first section of the main config hash is correct. Section 2 has
keys and values for both sections 1 and 2, section 3 has 1,2 and 3 etc.
One way around this that I tried was de-reference the reference in to a
hash take a reference to this new hash and then make the first reference
undef. The code I used was like this

$href1 = \%section;
$href2 = {%{$href1}};
$href1 = undef;
return $href2;

But this still failed in the same way. It looks like rather than the
'chain' of references I expected that all references point back to the
original data. So to my question how do I copy data using references,
but keep the copies detached from each other?
Thanks in advance
 
G

Gunnar Hjalmarsson

Mark said:
The config is then held in a hash of hashes. The problem I'm
having is getting the hash with the key value pairs stored in the
main config hash. I've written a sub routine that reads the key
value pairs and then returns a reference to this hash. The
problem is that because there is a reference back to this hash,
even with it being a local hash (created with my) to that sub, it
never goes out of scope. Hence only the first section of the main
config hash is correct. Section 2 has keys and values for both
sections 1 and 2, section 3 has 1,2 and 3 etc.

Speak less English and more Perl!!

Please post a short but complete program that illustrates the problem.
 
Z

Zebee Johnstone

In comp.lang.perl.misc on Sun, 22 Aug 2004 09:48:19 GMT
Mark Keightley said:
hash. I've written a sub routine that reads the key value pairs and
then returns a reference to this hash. The problem is that because
there is a reference back to this hash, even with it being a local hash
(created with my) to that sub, it never goes out of scope. Hence only
the first section of the main config hash is correct. Section 2 has
keys and values for both sections 1 and 2, section 3 has 1,2 and 3 etc.

NO idea how you are working out what pairs go with what section name,
but...

Can you read the pairs for a section into a hash local to the
subroutine, then put that hash into the main one?

so you pass $mainhash, work on $localhash, then put the stuff in
$localhash into $mainhash and pass $mainhash back.

Zebee
 
J

John W. Krahn

Mark said:
I'm currently writing a script to read windows style config files. You
know the sort of file that reads like this

[section name]
key1 = value1
key2 = value2

[another section name]
...

This appears to do what you want (tested on C:\WINDOWS\WIN.INI):

use warnings;
use strict;
use Data::Dumper;

my $file = '/mnt/windows/WINDOWS/WIN.INI';
open my $IN, '<', $file or die "Cannot open $file: $!";

my ( $section, %data );
while ( <$IN> ) {
next unless /\S/;
s/\s+\Z//; # used this instead of chomp because of Windows newline
if ( /^\[(.+)\]$/ ) {
$section = $1;
next;
}
my ( $key, $val ) = split /\s*=\s*/, $_, 2;
$data{ $section }{ $key } = $val;
}

print Dumper \%data;

__END__



John
 
A

Anno Siegel

Mark Keightley said:
Hi

I'm currently writing a script to read windows style config files. You
know the sort of file

No, I don't.
that reads like this

[section name]
key1 = value1
key2 = value2

[another section name]
...
Aha.

The config is then held in a hash of hashes. The problem I'm having is

[snip lots of prose]

Show your code instead of a verbal description.

Assuming a moderate amount of data and standard line feeds, this
reads a file structured as you describe into a HoH %h:

my ( undef, %h) = split /\[(.*?)\]\n/, do { local $/; <DATA> };
$_ = { map split( /\s*=\s*/), split /\n/ } for values %h;

The first line builds a hash whose keys are the section names and
whose values are (multiline) strings containing the key/value pairs.
The second line transforms each set of key/value pairs into the equivalent
hash.

Anno
 
B

Brian McCauley

Mark said:
I'm currently writing a script to read windows style config files.

Is this a learning exercise or is there some other reason you don't just
use one of the modules on CPAN that do this?
So to my question how do I copy data using references,
but keep the copies detached from each other?

This is FAQ: "How do I [...] copy a recursive data structure?"
 
M

Mark Keightley

Mark said:
Hi

I'm currently writing a script to read windows style config files. You
know the sort of file that reads like this

[section name]
key1 = value1
key2 = value2
....

Thanks to for all the responses, and sorry for the lack of code (it was
a bit of a mess!). It turns out the way I was going the long way around
for the soluiton. You live and learn. I've now used the exmaple given
John W Krahn as the bais for my script, which yes was done purly as an
excercise.
Thanks again to all.
 
J

Joe Smith

John said:
s/\s+\Z//; # used this instead of chomp because of Windows newline

That comment is misleading. The chomp() function works in win32 perl
for win32 files. If you're talking about a win32 file being processed
in a *nix enviroment, you should say so.
-Joe
 
J

John W. Krahn

Joe said:
That comment is misleading. The chomp() function works in win32 perl
for win32 files. If you're talking about a win32 file being processed
in a *nix enviroment, you should say so.

Maybe you noticed where I opened the file as:

my $file = '/mnt/windows/WINDOWS/WIN.INI';

:)

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top