Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Sounds simple, but I can't seem to get this to work, I'm trying to move some configuration data outside the program to a seperate file so it can be read in. This is the data as it currently exists in the program:
my $record = REC->new( NAME => 'John Smith', AGE => '15', RANK => 'Tier 1', URL => 'http://somesite.com', );
This is the config file I want to move it to:
NAME=John Smith AGE=15 RANK=Tier 1 URL=http://somesite.com )
And the snippet of code I've current mangled together:
my record =map{ s/#.*//; s/^\s+//; s/\s+$//; m/(.*?)\s*=\s*(.*)/; } read_file($file);
However using Data::Dumper I find that the structures are different, with the REC variable missing from my attempt. Can some kind monk enlighten me as to what I'm doing wrong in the code?

Replies are listed 'Best First'.
Re: read a hash from a file
by hdb (Monsignor) on Apr 16, 2013 at 06:23 UTC

    You seem to be using some modules to do your work. Could you please specify which they are. The code below is just rephrasing your snippet and loads the data into a hash.

    use strict; use warnings; use Data::Dumper; my %data = map { s/#.*//; # remove comments s/^\s+//; # remove leading white space s/\s+$//; # remove trailing white space m/(.*?)\s*=\s*(.*)/; # split on =, ignoring surrounding spaces } <DATA>; print Dumper(%data); __DATA__ NAME=John Smith AGE=15 RANK=Tier 1 URL=http://somesite.com

    What is missing is probably something like my $record = REC->new( %data ); but I cannot test this hypothesis as I don't where REC comes from. Hope this helps...

      I'm using File::Slurp
      #!/usr/bin/perl use strict; use warnings; use File::Slurp; use Data::Dumper; $file="config.txt"; my %record =map{ s/#.*//; s/^\s+//; s/\s+$//; m/(.*?)\s*=\s*(.*)/; } read_file($file); print Dumper (\%record);
      The dump from my code is
      $VAR1={ 'Name' =>John Smith', 'URL' => '15', 'RANK' => 'Tier 1', 'URL' => 'http://somesite.com' };
      but when the data is in the code, the dump is
      $VAR1= bless( { 'Name' =>John Smith', 'URL' => '15', 'RANK' => 'Tier 1', 'URL' => 'http://somesite.com' }, 'REC' );

        You are also having REC->new which must be provided by some module. Which one is that?

Re: read a hash from a file
by kcott (Archbishop) on Apr 16, 2013 at 10:11 UTC

    ++hdb (x4) for persevering while bits of information were slowly revealed.

    You can probably instantiate your REC objects like this:

    my $record = REC::->new( map { s/#.*$//; /^\s*([^=]+)=(.*?)\s*$/ ? ($1, $2) : () } read_fil +e($file) );

    Here's my test:

    $ perl -Mstrict -Mwarnings -e ' my $raw_data = q{ # Some comment NAME=John Smith AGE=15 # years only! RANK=Tier 1 URL=http://somesite.com URI=http://example.com }; package REC; my @req_args = qw{NAME AGE RANK URL}; sub new { my ($class, %args) = @_; exists $args{$_} or die "FAILED: $_" for @req_args; bless { %args } => $class; } sub print_for_config { my $self = shift; print "$_=", $self->{$_}, "\n" for @req_args; } package main; print "=" x 20, "\nDATA IN\n", "=" x 20, "\n$raw_data\n"; my $record = REC::->new( map { s/#.*$//; /^\s*([^=]+)=(.*?)\s*$/ ? ($1, $2) : () } split /\n/ => $raw_data ); print "=" x 20, "\nDATA OUT\n", "=" x 20, "\n"; $record->print_for_config; ' ==================== DATA IN ==================== # Some comment NAME=John Smith AGE=15 # years only! RANK=Tier 1 URL=http://somesite.com URI=http://example.com ==================== DATA OUT ==================== NAME=John Smith AGE=15 RANK=Tier 1 URL=http://somesite.com

    If you use strict and warnings, you can avoid code like this:

    my record =map{

    I'll also draw your attention to the following guidelines:

    -- Ken

Re: read a hash from a file
by BillKSmith (Monsignor) on Apr 16, 2013 at 12:51 UTC
    CPAN has several modules for reading and writting config (.ini) files. This would probably be a better format
    Bill