Skip to content

Instantly share code, notes, and snippets.

@xtetsuji
Created July 27, 2012 08:34
Show Gist options
  • Save xtetsuji/3186848 to your computer and use it in GitHub Desktop.
Save xtetsuji/3186848 to your computer and use it in GitHub Desktop.
Recursive {en,de}code version's Data::Dumper::Dumper() for having perl internal string.
# -*- cperl -*-
# ogata 2012/07/22
# ogata 2012/07/27
use strict;
use warnings;
use Data::Dumper;
use Scalar::Util qw(reftype readonly);
sub DumperRecursive ($) {
my $arg = shift;
encode_recursive($arg);
my $str = Dumper($arg);
decode_recursive($arg);
return $str;
}
sub printDumperRecursive ($) {
my $arg = shift;
open my $stdout_raw, '>&1'
or die ">&1 dup failed: $!";
print {$stdout_raw} DumperRecursive($arg);
}
*p = \&printDumperRecursive;
sub encode_recursive {
die "argument number must be one." if @_ != 1;
my $arg = $_[0];
if ( !ref $arg ) { # string
$_[0] = encode('utf-8', $arg) if !readonly $_[0];
}
elsif ( ref $arg eq 'ARRAY' || reftype $arg eq 'ARRAY' ) {
encode_recursive($_) for @$arg;
}
elsif ( ref $arg eq 'HASH' || reftype $arg eq 'HASH' ) {
encode_recursive($_) for values %$arg;
}
}
sub decode_recursive {
die "argument number must be one." if @_ != 1;
my $arg = $_[0];
if ( !ref $arg ) { # string
$_[0] = decode('utf-8', $arg) if !readonly $_[0];
}
elsif ( ref $arg eq 'ARRAY' || reftype $arg eq 'ARRAY' ) {
decode_recursive($_) for @$arg;
}
elsif ( ref $arg eq 'HASH' || reftype $arg eq 'HASH' ) {
decode_recursive($_) for values %$arg;
}
}
1;
=pod
=encoding utf-8
=head1 NAME
dumper-utf8.pl - Data::Dumper::Dumper() UTF-8 encode (destruct) mode.
=head1 SYNOPSYS
# in your script
BEGIN { require "path/to/dumper-utf8.pl"; } # fast compile for left-op
### some code...
# dump
printDumperRecursive($some_structure);
# or
p $some_structure; # shortcut.
=head1 NOTICE
If you solve this "Data::Dumper perl internal string escape problem" lightly,
write following code with "use Data::Dumper;".
use Data::Dumper;
{
package Data::Dumper;
sub qquote { return shift; }
}
$Data::Dumper::Useperl = 1;
This information is general solution.
Search websites with this keywords.
=head1 SUBROUTINS
=head2 B<DumperRecursive>
my $var1_str = DumperRecursive($some_structure);
Recursive encode elements version of Data::Dumper::Dumper().
Argument number must be 1. this module not support plural argument
like Data::Dumper::Dumper().
CAVEATS: Possibly this subroutine *DESTRUCT* 1st argument.
=head2 B<printDumperRecursive>
print DumperRecursive($arg);
also can be written
printDumperRecursive($arg);
as shortcut and more.
DumperRecursive() gives encode()d string.
If (e.g.) *STDOUT is applied PerlIO ':utf8' (binmode STDOUT, ':utf8'),
following code output string is broken on console.
print DumperRecursive($arg);
However printDumperRecursive() uses non-PerlIO duplicated STDOUT (pure fd=1),
because this problem does not occure.
CAVEATS: ditto.
=head2 p
Shortcut of printDumperRecursive().
p $arg; # FOR DEBUG
Inspire from Ruby.
If you use this wrting style, require() this script in BEGIN { ... } block.
Or else syntax "p $arg" may be parsed "$arg->p" as perl interpriter.
=head1 LIMITATION
This version has following limitation.
=over
=item hash reference's keys encode.
=back
=head1 AUTHOR
OGATA Tetsuji E<lt>tetsuji.ogata {at} gmail.comE<gt>.
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2012 by OGATA Tetsuji.
This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment