Breaking reference chians

Discussion in 'Perl Misc' started by Mark Keightley, Aug 22, 2004.

  1. 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
     
    Mark Keightley, Aug 22, 2004
    #1
    1. Advertising

  2. Mark Keightley wrote:
    > 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.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 22, 2004
    #2
    1. Advertising

  3. In comp.lang.perl.misc on Sun, 22 Aug 2004 09:48:19 GMT
    Mark Keightley <> wrote:
    > 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
     
    Zebee Johnstone, Aug 22, 2004
    #3
  4. Mark Keightley wrote:
    >
    > 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
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Aug 22, 2004
    #4
  5. Mark Keightley

    Anno Siegel Guest

    Mark Keightley <> wrote in comp.lang.perl.misc:
    > 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
     
    Anno Siegel, Aug 22, 2004
    #5
  6. Mark Keightley wrote:

    > 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?"
     
    Brian McCauley, Aug 22, 2004
    #6
  7. Mark Keightley wrote:

    > 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.
     
    Mark Keightley, Aug 22, 2004
    #7
  8. A. Sinan Unur, Aug 22, 2004
    #8
  9. Mark Keightley

    Joe Smith Guest

    John W. Krahn wrote:

    > 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
     
    Joe Smith, Aug 23, 2004
    #9
  10. Joe Smith wrote:
    > John W. Krahn wrote:
    >
    >> 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.


    Maybe you noticed where I opened the file as:

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

    :)

    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Aug 23, 2004
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. MJackson

    Breaking apart MBOX

    MJackson, Feb 19, 2004, in forum: Perl
    Replies:
    1
    Views:
    576
    Gunnar Hjalmarsson
    Feb 19, 2004
  2. Replies:
    0
    Views:
    583
  3. Peter Afonin
    Replies:
    4
    Views:
    428
    Natty Gur
    Jul 10, 2003
  4. brian lanning
    Replies:
    0
    Views:
    611
    brian lanning
    Jul 29, 2003
  5. Amy
    Replies:
    0
    Views:
    519
Loading...

Share This Page