The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Basset::Object::Conf - used to read conf files

AUTHOR

Jim Thomason, jim@jimandkoka.com

DESCRIPTION

It's good not to set up default values inside of your module. Believe me, I know. Lord knows I've gotten chewed out enough for Carp::Notify having the defaults in the module. Anyway, this module includes instructions for the conf file format, how the read_conf_file method works, and some bits of interaction with the rest of the system. See Basset::Object for more information.

SET-UP

You'll need to specify your conf files. There is the @conf_files array, toss in as many conf files as you'd like

 my @conf_files = qw(
        /etc/mail.bulkmail.cfg
        /etc/mail.bulkmail.cf2
 );
 

It'll just silently ignore any conf files that aren't present, so don't expect any errors. That's to allow you to place multiple conf files in for use on multiple servers and then not worry about them.

Multiple conf files are in significance order. So if mail.bulkmail.cfg and mail.bulkmail.cf2 both define a value for 'foo', then the one in mail.bulkmail.cfg is used. And so on, conf files listed earlier are more important. There is no way for a program to later look at a less significant conf value.

read_conf_file

read_conf_file will read in the conf files specified in the @conf_files array up at the top.

You can also pass in a list of conf files to read, in most to least significant order, same as the @conf_files array.

 my $conf = Mail::Bulkmail::Object->read_conf_file();
 or
 my $conf = Mail::Bulkmail::Object->read_conf_file('conf_files' => '/other/conf.file');
 or
 my $conf = Mail::Bulkmail::Object->read_conf_file('conf_files' => ['/other/conf.file', '/additional/conf.file']);
 

If you pass in a list of conf files, then the internal @conf_files array is bypassed.

$conf is a hashref of hashrefs. the main keys are the package names, the values are the hashes of the values for that object.

Example:

 #conf file
 define package Mail::Bulkmail
 
 use_envelope = 1
 safe_banned = 0
 
 define package Mail::Bulkmail::Server
 
 Smtp = your.smtp.com
 Port = 25
 
 $conf = {
        'Mail::Bulkmail' => {
                'use_envelope' => 1,
                'safe_banned' => 1
        },
        'Mail::Bulkmail::Server' => {
                'Smtp' => 'your.smtp.com',
                'safe_banned' => 1
        }
 };
 

read_conf_file is called at object initialization. Any defaults for your object are read in at this time. You'll rarely need to read the conf file yourself, since at object creation it is read and parsed and the values passed on.

Note that it will combine the conf file in with an existing conf hash. To get a fresh one, pass in the conf_hash parameter.

Basset::Object->read_conf_file('conf_hash' => {});

Be sure to read up on the conf file structure, below

The conf file is only re-read if it has been modified since the last time it was read.

CONF FILE specification

Your conf files are very important. You did specify them up in the @conf_files list above, right? Of course you did.

But now you need to know how they look. They're pretty easy.

Each line of the conf file is a name = value pair.

 ERRFILE = /path/to/err.file

Do not put the value in quotes, or they will be assigned.

 ERRFILE = /path/to/err.file            #ERRFILE is /path/to/err.file
 ERRFILE = "/path/to/err.file"          #ERRFILE is "/path/to/err.file"

the conf file is analyzed by the object initializer, and then each value is passed to the appropriate object upon object creation. So, in this case your ERRFILE class_attribute would be set to ERRFILE leading and trailing whitespace is stripped.

 so these are all the same:
 ERRFILE = /path/to/err.file
    ERRFILE        =     /path/to/err.file
            ERRFILE =        /path/to/err.file            
                                                                                        ^^^^^extra spaces

Sometimes it is insufficient to have only one conf file, but inappropriate to add more to the conf_files array. In these cases, it is best to use the include file directive.

include file subconf.cfg

When an include file directive is encountered, processing of the current conf file is suspended and the subfile is read in and processed first. After it is finished, the current file continues as before. This is best used in conjunction with the user restriction options to have one single global conf file that points to multiple different user files, allowing each user to configure his own options as appropriate.

Your conf file is read by read_conf_file. As you saw in the docs for read_conf_file, it creates a hashref. The top hashref has keys of package names, and the conf->{package} hashref is the name value pairs. To do that, you'll need to define which package you're looking at.

 define package SomeClass

 define package OtherClass
 
 ERRFILE = /path/to/err.file
 

So ERRFILE is now defined for OtherClass, but not for SomeClass (unless of course, OtherClass is a sub-class of SomeClass)

If you do not define a package, then the default package is assumed.

Multiple entries in a conf file take the last one.

 define package SomeClass
 
 ERRFILE = /path/to/err.file
 ERRFILE = /path/to/err.other.file
 

so SomeClass->ERRFILE is /path/to/err.other.file There is no way to programmatically access /path/to/err.file, the value was destroyed, even though it is still in the conf file.

There is one magic value token...undef

 ERRFILE = undef
 

This will set ERRFILE to the perl value 'undef', as opposed to the literal string "undef"

Sometimes, you will want to give a conf entry multiple values. Then, use the @= syntax.

 define package SomeClass
 
 foo = 7
 bar @= 8
 bar @= 9
 

SomeClass->foo will be 7, SomeClass->bar will be [8, 9]

Also, you may sometimes wish to specify a hash table in the conf file. In that case, use the %= syntax.

 define package SomeClass
 
 baz %= this=those
 baz %= him=her
 baz %= me=you

SomeClass->baz will be {this => those, him => her, me => you}

There is no way to assign a value more complex than a scalar, arrayref, or hashref.

Comments are lines that begin with a #

 #enter the SomeClass package
 define package SomeClass

 #connections stores the maximum number of connections we want
 connections = 7
 

If you want to get *really* fancy, you can restrict values to the user that is running the script. Use the :ID syntax for that.

 define package SomeClass
 
 #user 87 gets this value
 87:foo = 9
 
 #user 93 gets this value
 93:foo = 10
 
 #everyone else gets this value
 foo = 11
 

SAMPLE CONF FILE

 #this is in the default package
 ERRFILE = /path/to/err.file
 
 define package Mail::Bulkmail::Server
 #set our Smtp Server
 Smtp   = your.smtp.cpm
 
 #set our Port
 Port   = 25
 
 define package Basset::SubClass
 
 #store the IDs of the server objects we want to use by default
 
 servers @= 7
 servers @= 19
 servers @= 34

Object attributes must be prepended with a '-' sign. This is syntax swiped from objective-C. In Objective-C, class methods begin with a "+" and object methods begin with a "-".

 #set class attribute foo to 7
 foo    = 7
 
 #set object attribute bar to 8
 -bar   = 8

Basset::Object's initializer requires the prepending '-'. This is used for objects that should receive a default value of some sort from the conf file. Values not prepending with a '-' will not be called by the object initializer when new objects are created.

GRAMMAR

In fact, we'll even get fancy, and specify an ABNF grammar for the conf file.

        CONFFILE = *(LINE)                                      ; a conf file consists of 0 or more lines
        
        LINE = (
                        DEFINE                  ; definition line
                        / INCLUDE               ; include line
                        / COMMENT               ; comment line
                        / EQUATION              ; equation line
                        / *(WSP)                ; blank line
                ) "\n"                          ; followed by a newline character
        
        DEFINE = "define package" TEXT
                
        INCLUDE = "include file" TEXT
                        
        COMMENT = *(WSP) "#" TEXT
        
        EQUATION = *(WSP) (VARIABLE / USER_VARIABLE) 0*1("-") *(WSP)
                (EQUATION_SYMBOL *(WSP) VALUE *(WSP) / "%=" *(WSP) VARIABLE *(WSP) "=" *(WSP) VALUE)
        
        USER_VARIABLE = USER *(WSP) ":" *(WSP) VARIABLE
        
        USER = 1*(DIGIT)
        
        EQUATION_SYMBOL = "=" / "@="
        
        VALUE = *(TEXT)
        
        VARIABLE = *(TEXT)
        
        TEXT = VISIBLE *(VISIBLE / WSP) [VISIBLE]
        
        VISIBLE = %d33-%d126    ; visible ascii characters

SEE ALSO

Also see Basset::Object, Basset::Object::Persistent

COPYRIGHT (again)

Copyright and (c) 2002 James A Thomason III (jim@jimandkoka.com). All rights reserved. Basset::Object::Conf is distributed under the terms of the Perl Artistic License, except for items where otherwise noted.

CONTACT INFO

So you don't have to scroll all the way back to the top, I'm Jim Thomason (jim@jimandkoka.com) and feedback is appreciated. Bug reports/suggestions/questions/etc. Hell, drop me a line to let me know that you're using the module and that it's made your life easier. :-)

1 POD Error

The following errors were encountered while parsing the POD:

Around line 465:

=cut found outside a pod block. Skipping to next block.