Config::Access::Driver

De-/Serialising INI files into ready-to-use object structures

Overview

Config::Access::Driver reads, manipulates, and writes INI configuration files as ready-to-use objects. Instead of navigating raw hashes-of-hashes or defining custom configuration classes, you get objects with convenient access methods from the moment the file is parsed — read → inspect → modify → write with zero preparation.

It combines the convenient file access of File::Access::Driver with the convenient object access of Object::Meta, adding an INI parser and ready-made section structures on top.

Motivation

This library was conceived as result of the experience using Config::IniHash extensively and the clumsy code it produces.
So, it aims to make the work de-/serialising INI files easier and more streamlined.
Especially data manipulation is simplified with the use of the convenient Object::Meta library.
But also file manipulation becomes more easier thanks to the use of the convenient File::Access::Driver library.

Key Features

Installation

perl Makefile.PL
make
make test
make install

Requires: Perl5.010.

Usage

use Config::Access::Driver;

my $config_file = Config::Access::Driver::->new(
    ( 'filedirectory' => $config_directory, 'filename' => $config_file_name ) );

my $config = $config_file->readList();

#Free the System Resources
$config_file->freeResources();

if ( $config_file->getErrorCode() == 0 ) {
    my $server_section = $config->getConfigSectionbyName($server_prefix);

    if ( defined $server_section ) {

        #------------------------
        #Server Backup Configuration

        #Value with fallback default in one call
        $backup_directory = $server_section->get( 'BACKUPDIR', $backup_directory );

        #Existence check without hash plumbing
        if ( $server_section->hasKey('SAVEDAYS') ) {
            $save_days = $server_section->get('SAVEDAYS');
        }
        else    #The Server Configuration is not complete
        {
            $error_message .=
              "Server '$server_prefix': Server is not completely configured.\n"
              . "Assuming SAVEDAYS = '$save_days'\n";
        }
    }
}

For a quick one-shot read without managing the driver instance:

my $config = Config::Access::Driver::readConfigSectionList('/path/to/config.ini');

#Fast indexed lookup by section name
my $db_config = $config->getConfigSectionbyName('database');

Comparison with Config::IniHash

The same task — read a backup configuration, validate required keys — written with Config::IniHash:

$config = ReadINI $config_file_path;

if ( defined $config ) {
    if ( defined $config->{$server_prefix} ) {

        if ( defined $config->{$server_prefix}->{'BACKUPDIR'} ) {
            $backup_directory = $config->{$server_prefix}->{'BACKUPDIR'};
        }

        if ( defined $config->{$server_prefix}->{'MAILTO'} ) {
            $smailto = $config->{$server_prefix}->{'MAILTO'};
        }
        else    #The Server Configuration is not complete
        {
            $error_message .=
              "Server '$server_prefix': Server is not completely configured.\n";
        }
    }
}

Every access repeats the full hash-of-hashes path$config->{$server_prefix}->{'KEY'} — wrapped in exists guards. Reconstructing numerically keyed options into an array gets worse:

if ( exists $config->{ $server_prefix . $backup_plan_section } ) {
    foreach ( keys %{ $config->{ $server_prefix . $backup_plan_section } } ) {
        $#backup_plan = $_ if ( $_ + 1 > @backup_plan );
        $backup_plan[$_] = $config->{ $server_prefix . $backup_plan_section }->{$_};
    }
}

With Config::Access::Driver, the same intent becomes named, typed method calls:

$backup_directory = $server_section->get( 'BACKUPDIR', $backup_directory );

if ( $server_section->hasKey('MAILTO') ) { ... }

The difference compounds in real applications: every hash-path access in the Config::IniHash version is a potential undef dereference and must be guarded individually, while the object API concentrates those checks into get defaults, hasKey(), and the driver's Error Code.

Where the trade-off lies

Other INI readers are typically faster on raw parsing, and hash-of-hashes returns plain data with no dependencies. But their speed is paid for in application code: hash chains to repeat, existence checks to hand-roll, and no object behaviour whatsoever. Config::Access::Driver is optimised for developer productivity and safe access patterns rather than absolute parse speed — lookups are still served through a name index rather than linear scans, and parsing itself is a single pass over the file lines.

Architecture

Config::Access::Driver           – File bound De-/Serialisation Driver
 └─ parent: File::Access::Driver – Reusable File Access Layer (I/O)
Config::Section::Parser          – parseLines ↔ buildString (De-/Serializer)
Config::Section::List            – Ordered, indexed list of Sections
Config::Section                  – Single INI section (options + value lists)
Object::Meta / Object::Meta::List – Lightweight meta-object indexing layer

Each layer is proven, published software in its own right — File::Access::Driver handles any file I/O task and Object::Meta provides indexed collections for arbitrary objects — with the Config::* layers adding only the INI-specific logic on top.

Dependencies

Runtime dependencies are intentionally minimal: | Module | Purpose | | :-- | :-- | | File::Access::Driver | Convenient file reading and writing | | Object::Meta | Indexed object collections |

Plus Data::Dump for development/debugging. No XS, no native compilation.

Author

Bodo (Hugo) Barwich

License

Distributed under the Artistic License / the same terms as Perl itself. See LICENSE for details.