Datafile-Hash
view release on metacpan or search on metacpan
lib/Datafile/Hash.pm view on Meta::CPAN
$has_real_nested = 1;
}
my %global_data;
for my $k ( keys %data ) {
next if ref $data{$k} eq 'HASH';
$global_data{$k} = delete $data{$k};
}
my $write_section;
$write_section = sub {
my ( $cur, $path ) = @_;
my $name = @$path ? join( '.', @$path ) : '';
print $fh "\n" unless ($first_section);
$first_section = 0;
if ( $name ne '' ) {
print $fh "[$name]\n";
push @messages, "> [$name]\n" if $verbose;
}
my $maxsize = 0;
for my $k ( sort grep { !ref $cur->{$_} } keys %$cur ) {
$maxsize = length($k) if length($k) > $maxsize;
}
for my $k ( sort grep { !ref $cur->{$_} } keys %$cur ) {
my $v = $cur->{$k};
my $needs_quoting =
( $v =~ /[#"'\r\n]/ || $v =~ /^\s+|\s+$/ || $v eq '' );
if ( $delim eq '=' && $needs_quoting ) {
$v =~ s/"/\\"/g;
$v = qq("$v");
}
my $line = sprintf "%-*s %s %s", $maxsize, $k, $delim, $v;
print $fh "$line\n";
$entry_count++;
}
for my $sub ( sort grep { ref $cur->{$_} eq 'HASH' } keys %$cur ) {
$write_section->( $cur->{$sub}, [ @$path, $sub ] );
}
};
if ( keys %global_data ) {
$write_section->( \%global_data, [] );
}
for my $top ( sort keys %data ) {
$write_section->( $data{$top}, [$top] );
}
}
print $fh "#EOF\n" if $comment_char eq '#';
close $fh
or return ( 0, ["ERROR: failed to close '$tmp': $!"] );
if ( $backup && -f $filename ) {
rename( $filename, $filename . '.bak' )
or push @messages,
"WARNING: backup to ${filename}.bak failed: $!";
}
rename( $tmp, $filename )
or return ( 0, ["ERROR: failed to rename '$tmp' to '$filename': $!"] );
chmod $prot, $filename;
push @messages, "- $entry_count entries written to $filename\n"
if $verbose;
return ( $entry_count, \@messages );
}
1;
__END__
=encoding UTF-8
=head1 NAME
Datafile::Hash - Pure-Perl utilities for datafiles and INI-style config files with multi-level sections
=head1 LICENSE
This module is free software.
You can redistribute it and/or modify it under the same terms as Perl itself.
=head1 SYNOPSIS
use Datafile::Hash qw(readhash writehash);
my %config;
readhash('config.ini', \%config, {
delimiter => '=', # INI mode
group => 2, # nested hashes (default)
verbose => 1,
});
# $config{section}{subsection}{key} = 'value'
# Flat key-value file example
readhash('settings.txt', \%config, {
delimiter => '=', # still INI mode
group => 0, # flat hash, ignore sections
});
writehash('config.ini', \%config, {
backup => 1,
comment => ['Auto-generated - do not edit manually', scalar localtime],
});
=head1 DESCRIPTION
Lightweight pure-Perl module for reading and writing key-value data files,
including full INI-style files with multi-level sections.
Supports flat files, dotted-key notation, or true nested hashes.
Safe atomic writes and consistent error handling.
=head1 FUNCTIONS
=head2 readhash($filename, $hash_ref, \%options)
Loads key-value data into a hash reference.
( run in 2.083 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )