YAML::DumpとかJSON::objToJsonみたいな感じでshのsyntaxでダンプru

例外処理とかユルユルですが。

#!/usr/bin/env perl
# Time-stamp: <2007-10-09 20:01:58 JST, hirose31>

use strict;
use warnings;
use utf8;
use Carp;
use String::ShellQuote;
use Test::Base;

### ========================================================================
plan tests => 1 * blocks;

filters {
    input    => [qw(eval)],
    expected => [qw()],
};

run {
    my $block = shift;

    my $out;
    eval { $out = objToSh($block->input) };
    $out =~ s/\s+\z// if $out;

    is($out, $block->expected, $block->name);
};

### ========================================================================
sub objToSh {
    my($obj) = @_;
    my $out;

    my $type = ref $obj;
    return unless $type;

    if ($type eq 'HASH') {
        while (my ($k,$v) = each %$obj) {
            my $vtype = ref $v;
            if (! $vtype) {
                $out .= sprintf "%s=%s ", _sh_name($k), _sh_value($v);
            } elsif ($vtype eq 'ARRAY') {
                $out .= sprintf "%s=(", _sh_name($k);
                $out .= join " ", _sh_value(@$v);
                $out .= ") ";
            }
        }
        return $out;
    }
    return;
}

sub _sh_name {
    my($k) = @_;
    $k =~ /^[a-zA-Z_][a-zA-Z_0-9]+$/ or croak 'contain invalid character';
    return $k;
}
sub _sh_value {
    shell_quote_best_effort @_;
}

__END__
=== name=val
--- input: { varname => 'valval' }
--- expected: varname=valval

=== value contain space
--- input: { varname => 'foo bar baz' }
--- expected: varname='foo bar baz'

=== value contain single quote
--- input: { varname => q{val'val} }
--- expected: varname='val'\''val'

=== value contain double quote
--- input: { varname => q{val"val} }
--- expected: varname='val"val'

=== value contain single and double quote
--- input: { varname => q{val'val"val} }
--- expected: varname='val'\''val"val'

=== hash
--- input: { one => 'ichi', two => 'ni', three => 'san' }
--- expected: three=san one=ichi two=ni

=== array
--- input: { ary => [qw(foo bar baz)] }
--- expected: ary=(foo bar baz)

=== array contains single and double quote
--- input: { ary => ['foo', q{ba'r}, q{ba"z}] }
--- expected: ary=(foo 'ba'\''r' 'ba"z')

=== invalid name  start with digit
--- input: { '0varname' => 'valval' }
--- expected eval: undef

=== invalid name  contain hyphen
--- input: { 'var-name' => 'valval' }
--- expected eval: undef

--- LAST

# for Emacsen
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
# indent-tabs-mode: nil
# coding: utf-8
# End:

# vi: set ts=4 sw=4 sts=0 :