Skip to content

Commit

Permalink
Fix o2h handling of scalars with dash (fixes #20)
Browse files Browse the repository at this point in the history
  • Loading branch information
haukex committed Dec 13, 2023
1 parent d5391db commit 10a8b75
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 9 deletions.
4 changes: 4 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Revision history for Perl extension Util::H2O.

0.24 Wed, Dec 13 2023
- fix a bug where o2h would die on scalars that looked like options
(Thanks @oodler577!)

0.22 Sat, Jan 28 2023 commit d8d5d8b2acc0f6518c7e09b26df0ea486d118006
- fix a bug where -arrays was not passed into hashes of hashes

Expand Down
2 changes: 1 addition & 1 deletion Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ WriteMakefile(
provides => {
'Util::H2O' => {
file => 'lib/Util/H2O.pm',
version => '0.22',
version => '0.24',
},
},
resources => {
Expand Down
27 changes: 21 additions & 6 deletions lib/Util/H2O.pm
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Util::H2O - Hash to Object: turns hashrefs into objects with accessors for keys
=cut

our $VERSION = '0.22';
our $VERSION = '0.24';
# For AUTHOR, COPYRIGHT, AND LICENSE see the bottom of this file

our @EXPORT = qw/ h2o /; ## no critic (ProhibitAutomaticExportation)
Expand Down Expand Up @@ -500,20 +500,35 @@ If you specify this option, nested arrayrefs are descended into as well.
This option was added in v0.20.
=item C<-->
This string ends the option processing, allowing you to pass scalar values to
C<o2h> that would otherwise be interpreted as options.
The C<o2h> function is special-cased such that a call C<o2h("--")> returns
C<"--"> instead of throwing an error.
This was added in v0.24 in order to fix a bug with scalars beginning with
C<"-"> in earlier versions of this module. Users of C<o2h> are advised to
upgrade.
=back
=cut

sub o2h { ## no critic (RequireArgUnpacking)
my ($arrays);
while ( @_ && $_[0] && !ref$_[0] && $_[0]=~/^-/ ) {
if ($_[0] eq '-arrays' ) { $arrays = shift }
else { croak "unknown option to o2h: '$_[0]'" }
unless ( @_==1 && $_[0] && !ref$_[0] && $_[0]eq'--' ) { ## no critic (ProhibitNegativeExpressionsInUnlessAndUntilConditions)
while ( @_ && $_[0] && !ref$_[0] && $_[0]=~/^-/ ) {
if ($_[0] eq '-arrays' ) { $arrays = shift }
elsif ($_[0] eq '--') { shift; last }
else { croak "unknown option to o2h: '$_[0]'" }
}
}
croak "missing argument to o2h" unless @_;
my $h2o = shift;
croak "too many arguments to o2h" if @_;
my @args = ( $arrays ? (-arrays) : () );
my @args = ( ( $arrays ? (-arrays) : () ), '--' );
if ( ref($h2o) =~ $_PACKAGE_REGEX )
{ return { map { $_ => o2h(@args, $h2o->{$_}) } keys %$h2o } }
elsif ( $arrays && ref $h2o eq 'ARRAY' )
Expand Down Expand Up @@ -545,7 +560,7 @@ One common use case for this module is to make accessing hashes nicer, like for
example those you get from L<Config::Tiny|Config::Tiny>. Here's how you can
create a new C<h2o> object from a configuration file:
use Util::H2O 0.18 qw/ h2o o2h /; # v0.18 for o2h
use Util::H2O 0.24 qw/ h2o o2h /; # v0.24 for o2h (with bugfixes)
use Config::Tiny 2.27; # v2.27 for writing file back out
my $config = h2o -recurse, {%{ Config::Tiny->read($config_filename) }};
Expand Down
19 changes: 17 additions & 2 deletions t/Util-H2O.t
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ L<http://perldoc.perl.org/perlartistic.html>.
=cut

use Test::More tests => 332;
use Test::More tests => 343;
use Scalar::Util qw/blessed/;
use Symbol qw/delete_package/;

Expand All @@ -31,7 +31,7 @@ sub warns (&) { my @w; { local $SIG{__WARN__} = sub { push @w, shift }; shift->(

diag "This is Perl $] at $^X on $^O";
BEGIN { use_ok 'Util::H2O' }
is $Util::H2O::VERSION, '0.22';
is $Util::H2O::VERSION, '0.24';

diag "If all tests pass, you can ignore the \"this Perl is too old\" warnings"
if $] lt '5.008009';
Expand Down Expand Up @@ -186,6 +186,21 @@ my $PACKRE = $Util::H2O::_PACKAGE_REGEX; ## no critic (ProtectPrivateVars)
is $h->{h}{z}{foo}->def, 456;
is ref $h->{c}, 'CODE';
is $h->{h}{x}, 'y';
# values that look like options
my $o2 = h2o { foo => -bar, x => -arrays, y=>'z' };
is $o2->foo, '-bar';
my $h2 = o2h $o2;
is ref $h2, 'HASH';
is_deeply $h2, { foo => '-bar', x => '-arrays', y=>'z' };
my $h3 = o2h -arrays, [ '--', 47 ];
is ref $h3, 'ARRAY';
is_deeply $h3, [ '--', 47 ];
is o2h(42), 42;
is o2h(0), 0; # coverage
ok exception { o2h(-42) };
is o2h('--', -42), -42;
is o2h('--'), '--';
ok exception { o2h('-arrays', '--') };
}
# o2h + -lock + -ro
{
Expand Down

0 comments on commit 10a8b75

Please sign in to comment.