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

NAME

OpenInteract2::Conversion::IniConfig - Parent class for converting perl configurations to INI format

SYNOPSIS

 use base qw( OpenInteract2::Conversion::IniConfig );
 
 sub get_field_order {
     return [ qw/ one two three four / ];
 }
 
 sub init {
     my ( $self ) = @_;
     $self->transforms({ three => \&_modify_three,
                         four  => \&_modify_four });
     return $self;
 }
 
 # Instead of numbers use categories:
 # < 0   - sub
 # < 5   - min
 # < 20  - norm
 # >= 20 - max
 
 sub _modify_three {
     my ( $name, $value ) = @_;
     return unless ( defined $value );
     if ( $value < 0 ) {
         return ( $name, 'sub' );
     }
     elsif ( $value < 5 ) {
         return ( $name, 'min' );
     }
     elsif ( $value < 20 ) {
         return ( $name, 'norm' );
     }
     else {
         return ( $name, 'max' );
     }
 }
 
 # Rename field to 'fore'
 
 sub _modify_four {
     my ( $name, $value ) = @_;
     return ( 'fore', $value );
 }

DESCRIPTION

This class provides methods to convert a serialized perl data structure into an INI file. There are restrictions on the structures -- you can have only one contained hash reference, and no subroutine references. But the resulting configuration is much easier for humans to read and edit.

METHODS

new( $old_content )

Creates a new object, initializing it with the text $old_content representing a serialized perl data structure. This is tested with structures serialized by Data::Dumper, but others probably work ok.

init()

Allows subclasses to perform initialization, normally to register transformations. Called just after object initialized in new() with the optional content passed in.

convert()

Perform the actual data conversion. You must have set the perl data structure content either in the constructor or by calling old_content() (with the text) or old_config() (with the actual data structure), otherwise the method will die. Similarly, if the content does not evaluate to a proper perl data structure, or if it evaluates to something other than a hashref, the method will die.

Otherwise we step through the hashref in the order defined by a subclass (using get_field_order()) and convert the value for each key into one or more key/value string pairs, possibly transforming the key and/or value before the conversion.

serialize( [ $raw_content ] )

Serializes $raw_content (or the return of raw_content() if not provided) into an INI-style configuration. This is stored in new_content() and also returned from the method.

old_config( [ \%config ] )

Gets/sets the configuration used to generate the INI. You can set the configuration directly rather than setting the serialized perl datastructure text in old_content().

old_content( [ $text ] )

Sets/returns the text used for the serialized perl data structure. This must be set (either here or in the constructor) before calling convert().

new_content()

Returns the generated content. This is set implicitly by serialize() and cannot be set externally.

raw_content()

Returns the raw content. This consists of an array of arrayrefs. Each arrayref is a section in the INI file -- the first member is the label and every remaining member is a key/value pair under that label.

This is set implicitly by convert() and cannot be set externally.

transforms( \%transforms )

Get/set the transformation routines for the configuration. See "Transforming Data" below for what the routines can do and what they should return.

Transforming Data

A subclass or caller has the ability to register transformation handlers with the converter. Each transformation handler is a code reference that is passed two arguments: a $name and $value. The $name is the name of the configuration key, the $value is its value. (duh) It's best to explain with an example:

 sub _modify_true_to_yes {
     my ( $name, $value ) = @_;
     return ( $name, 'no' )  unless ( $value );
     return ( $name, 'yes' );
 }

This will change something like:

 increment_field => 1,
 field_discover  => 0,

into:

 increment_field = yes
 field_discover  = no

You can change both the field name and the field value, and you must return both even if you don't modify them.

Normally a subclass with register these transformations in its init() method:

 sub init {
     my ( $self ) = @_;
     $self->transforms({ increment_field => \&_modify_true_to_yes,
                         field_discover  => \&_modify_true_to_yes });
    return $self;
 }

A common use of the transformations is to flatten a second-level hashref into an arrayref of parseable text. For instance, in the SPOPS configuration the 'creation_security' key has a hashref as a value, and the 'g' key of that hashref could have another hashref as a value. In the new configuration it cannot, so we need to change it to fit our scheme. One idea is to change:

 creation_security => {
   u => 'READ',
   g => { 3 => 'WRITE' },
   w => undef,
 }

into something like this:

 creation_security => {
   u => 'READ',
   g => [ '3:WRITE' ],
   w => undef,
 }

which the normal process can handle nicely.

BUGS

None known.

TO DO

Nothing known.

SEE ALSO

COPYRIGHT

Copyright (c) 2002-2004 Chris Winters. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

AUTHORS

Chris Winters <chris@cwinters.com>