Using OOP to load a config file

Discussion in 'Perl Misc' started by Prab_kar@hotmail.com, Mar 27, 2006.

  1. Guest

    Hi all,
    I'm fairly new to OOP in Perl and trying my hand to load a config file
    (in a 'key=value' format)using OOP. I've got stuck at a point and
    wonder if anyone of you could give me some pointers.

    Config file: Foo.conf
    Perl module: CfgLoader.pm
    Perl script: useOOP.pl

    For a given config file, Foo.conf with content along the lines,
    Key1=Value1, I'd like to access the keys and values from my Perl
    script, useOOP.pl, as, $obj->value("key1") ; which would give me
    "value1".

    In the following .pl/.pm below, I was able to load the config file and
    split the key/values, but dont know how to transfer that 'hash' back to
    the main program, useOOP.pl.
    I'll have to define another method/function, 'value', but dont know how
    to transfer the hash from the 'loadCfg' method to the new method or to
    return values from the new method to the calling script. Could any of
    you give some pointers, please? Thanks for your time,

    ------------------useOOP.pl:-----------------------------

    #!/usr/local/bin/perl

    use strict ;
    use warnings ;

    use CfgLoader ;

    my $obj = new CfgLoader() ;
    $obj->loadCfg("Foo.conf") ;

    --------------------------------------------------------------

    ------------------CfgLoader.pm-----------------------------
    package CfgLoader ;

    sub new ()
    {
    $class = shift ;
    $self = {} ;
    bless ($self,$class) ;
    }

    sub loadCfg()
    {
    my ($self,$file) = @_ ;
    print "Loading configuration: $file\n" ;

    open(IN,"$file") or die "Cant open $file: $!\n" ;
    while(<IN>)
    {
    chomp ;
    next if ( /^(#|$)/ ) ;
    ($key,$value) = split(/\=/,$_) ;
    print "Key: $key Value: $value\n" ;
    $hash{$key} = $value ;
    }
    close(IN) or die "Cant close file: $!\n" ;
    }

    # Required to retun 1
    1 ;
    -------------------------------------------------------------------------

    Thanks,
    Prabh
    , Mar 27, 2006
    #1
    1. Advertising

  2. Guest

    wrote:
    >
    > For a given config file, Foo.conf with content along the lines,
    > Key1=Value1, I'd like to access the keys and values from my Perl
    > script, useOOP.pl, as, $obj->value("key1") ; which would give me
    > "value1".
    >
    > ------------------CfgLoader.pm-----------------------------
    , Mar 27, 2006
    #2
    1. Advertising

  3. Brad Baxter Guest

    wrote:
    > $self{$key} = $value ;


    Simplistic and wrong.

    $self->{$key} = $value ;

    Sorry about that.

    --
    Brad
    Brad Baxter, Mar 27, 2006
    #3
  4. Anno Siegel Guest

    <> wrote in comp.lang.perl.misc:
    > wrote:
    > >
    > > For a given config file, Foo.conf with content along the lines,
    > > Key1=Value1, I'd like to access the keys and values from my Perl
    > > script, useOOP.pl, as, $obj->value("key1") ; which would give me
    > > "value1".
    > >
    > > ------------------CfgLoader.pm-----------------------------

    > .
    > .
    > .
    > > sub loadCfg()
    > > {
    > > my ($self,$file) = @_ ;
    > > print "Loading configuration: $file\n" ;
    > >
    > > open(IN,"$file") or die "Cant open $file: $!\n" ;
    > > while(<IN>)
    > > {
    > > chomp ;
    > > next if ( /^(#|$)/ ) ;
    > > ($key,$value) = split(/\=/,$_) ;
    > > print "Key: $key Value: $value\n" ;
    > > $hash{$key} = $value ;
    > > }
    > > close(IN) or die "Cant close file: $!\n" ;
    > > }

    >
    >
    > Dear Prabh,
    >
    > I noticed that you used "use strict;" and "use warnings;" in the
    > file "useOOP.pl". Good for you! However, it's also good to include
    > them in CfgLoader.pm, as they will point out (at least) one error to
    > you.
    >
    > Right off the bat, I see that you are populating %hash inside
    > loadCfg() when it is never declared. Instead of:
    >
    > $hash{$key} = $value;
    >
    > I think you mean to say:
    >
    > $self->{$key} = $value;
    >
    > that way you can use $obj->{key1} to retrieve "value1".


    I agree that the key/value pairs should probably go into the object and
    not in some class-global hash (though that is a valid alternative too).

    However, $obj->{key1} is no way to access an object. An object
    encapsulates its implementation, but $obj->{key1} exposes the
    implementation as a hash.

    Instead there should be accessor methods for each key expected in the
    config file to access the corresponding value (untested)

    sub get_key1 { $_[ 0]->{ key1} }

    etc.

    For this approach you need to know beforehand which keys can possibly
    appear in a config file. If you expect keys that aren't known until
    run time, a general accessor can be used:

    sub get_any_key {
    my ( $conf, $key) = @_;
    $conf->{ $key};
    }

    In that case, individual accessors can be derived from the general one

    sub get_key1 { shift()->get_any_key( key1) }

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Mar 28, 2006
    #4
  5. Anno Siegel Guest

    <> wrote in comp.lang.perl.misc:
    > wrote:
    > >
    > > For a given config file, Foo.conf with content along the lines,
    > > Key1=Value1, I'd like to access the keys and values from my Perl
    > > script, useOOP.pl, as, $obj->value("key1") ; which would give me
    > > "value1".
    > >
    > > ------------------CfgLoader.pm-----------------------------

    > .
    > .
    > .
    > > sub loadCfg()
    > > {
    > > my ($self,$file) = @_ ;
    > > print "Loading configuration: $file\n" ;
    > >
    > > open(IN,"$file") or die "Cant open $file: $!\n" ;
    > > while(<IN>)
    > > {
    > > chomp ;
    > > next if ( /^(#|$)/ ) ;
    > > ($key,$value) = split(/\=/,$_) ;
    > > print "Key: $key Value: $value\n" ;
    > > $hash{$key} = $value ;
    > > }
    > > close(IN) or die "Cant close file: $!\n" ;
    > > }

    >
    >
    > Dear Prabh,
    >
    > I noticed that you used "use strict;" and "use warnings;" in the
    > file "useOOP.pl". Good for you! However, it's also good to include
    > them in CfgLoader.pm, as they will point out (at least) one error to
    > you.
    >
    > Right off the bat, I see that you are populating %hash inside
    > loadCfg() when it is never declared. Instead of:
    >
    > $hash{$key} = $value;
    >
    > I think you mean to say:
    >
    > $self->{$key} = $value;
    >
    > that way you can use $obj->{key1} to retrieve "value1".


    I agree that the key/value pairs should probably go into the object and
    not in some class-global hash (though that is a valid alternative too).

    However, $obj->{key1} is no way to access an object. An object
    encapsulates its implementation, but $obj->{key1} exposes the
    implementation as a hash.

    Instead there should be accessor methods for each key expected in the
    config file to access the corresponding value (untested)

    sub get_key1 { $_[ 0]->{ key1} }

    etc.

    For this approach you need to know beforehand which keys can possibly
    appear in a config file. If you expect keys that aren't known until
    run time, a general accessor can be used:

    sub get_any_key {
    my ( $conf, $key) = @_;
    $conf->{ $key};
    }

    In that case, individual accessors can be derived from the general one

    sub get_key1 { shift()->get_any_key( 'key1') }

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.

    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Mar 28, 2006
    #5
  6. Guest

    Anno Siegel wrote:
    >
    > I agree that the key/value pairs should probably go into the object and
    > not in some class-global hash (though that is a valid alternative too).
    >
    > However, $obj->{key1} is no way to access an object. An object
    > encapsulates its implementation, but $obj->{key1} exposes the
    > implementation as a hash.
    >
    > If you expect keys that aren't known until
    > run time, a general accessor can be used:
    >
    > sub get_any_key {
    > my ( $conf, $key) = @_;
    > $conf->{ $key};
    > }



    I figure you could also make use of the AUTOLOAD function, like
    this:

    # Untested:
    sub AUTOLOAD
    {
    my $key = our $AUTOLOAD;
    $key =~ s/.*:://; # trim package name
    return $_->{$key} if exists $$_{$key};

    use Carp;
    croak "Undefined subroutine $AUTOLOAD called";
    }

    That way, he can retrieve a value with a call like:

    my $install_path = $configObject->install_path();

    to retrieve a value in his config file that defined like:

    install_path /home/user1/temp

    Of course, this AUTOLOAD function assumes that every config entry
    you'd ever want to retrieve has been specified in the config file. If
    it isn't, then it will assume that the code was trying to call an
    undefined function.

    I suppose that this little problem could be fixed by using the
    "fields" pragma to define the existing fields ahead of time by the
    programmer. However, the "use fields" approach wouldn't work very well
    if he/she wanted an arbitrary number of fields, but if he wants to
    hard-code what to retrieve in his code anyway, he should already know
    what fields to specify.

    -- Jean-Luc
    , Apr 3, 2006
    #6
    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. ABC
    Replies:
    1
    Views:
    793
    Richard Dudley
    Oct 24, 2005
  2. CSharpner
    Replies:
    0
    Views:
    1,001
    CSharpner
    Apr 9, 2007
  3. ABC
    Replies:
    1
    Views:
    357
    Patrick.O.Ige
    Oct 31, 2005
  4. Replies:
    1
    Views:
    123
  5. kampy
    Replies:
    9
    Views:
    318
    Steven D'Aprano
    Oct 19, 2012
Loading...

Share This Page