Skip Menu |

This queue is for tickets about the Data-Walk CPAN distribution.

Report information
The Basics
Id: 125308
Status: new
Priority: 0/
Queue: Data-Walk

People
Owner: GUIDO [...] cpan.org
Requestors: webster15july [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Subject: Top Level Object should not have a `container`
Date: Mon, 14 May 2018 00:35:59 +0530
To: bug-Data-Walk [...] rt.cpan.org
From: Prashant Karmakar <webster15july [...] gmail.com>
Data::Walk Version 2.01 assigns `container` and `type` for top-level objects in an inconsistent way. On one hand, A scalar at top level gets the arrayref of `@args` as `container`, and `ARRAY` as `type`. Whereas a hashref, or arrayref, at top-level gets *ITSELF* as the `container`, and its own ref type (`ARRAY|HASH`) as `type`. The latter behaviour is not consistent because it implies that the item is contained in itself. A set of rules for consistent behaviour regarding top-level objects can be: - Top level object passed to `walk` has `$Data::Walk::depth == 1`. - `$Data::Walk::container` and `$Data::Walk::type` is `undef` for such objects. (They have no container, and hence, no container type.) A patch against commit b3f9af86587a513d9a3a1e8f318ef6a30e328872 is included here. Summary of Changes: - new file: t/05bug-container-type-at-depth-one.t Tests the above consistent behaviour for the following calls of `Data::Walk::walk`: - Single hashref argument `walk sub { ... }, $hashref;` - Single arrayref argument `walk sub { ... }, $arrayref;` - Many argument with the first one as scalar `walk sub { ... }, 5, $hash,$arrayref;` - modified: t/04bug-container-type-by-depth.t Makes the test compliant to the above mentioned consistent behaviour. - modified: lib/Data/Walk.pm Fix setting of Top-Level Objects' container fix-setting-top-level-container.patch ------------------------------------- diff --git a/lib/Data/Walk.pm b/lib/Data/Walk.pm index 1ca491c..b714ce6 100755 --- a/lib/Data/Walk.pm +++ b/lib/Data/Walk.pm @@ -71,23 +71,7 @@ sub __walk { local $index = 0; foreach my $item (@args) { - local ($container, $type, $depth); - if (ref $item) { - if (UNIVERSAL::isa ($item, 'HASH')) { - $container = $item; - $type = 'HASH'; - } elsif (UNIVERSAL::isa ($item, 'ARRAY')) { - $container = $item; - $type = 'ARRAY'; - } else { - $container = \@args; - $type = 'ARRAY'; - } - } else { - $container = \@args; - $type = 'ARRAY'; - } - $depth = 0; + local $depth = 0; __recurse $options, $item; ++$index; } diff --git a/t/04bug-container-type-by-depth.t b/t/04bug-container-type-by-depth.t index 6bed43c..3f18435 100755 --- a/t/04bug-container-type-by-depth.t +++ b/t/04bug-container-type-by-depth.t @@ -23,14 +23,36 @@ use Test; use Data::Walk; BEGIN { - plan tests => 10; + plan tests => 20; } my $data = { foo => 'bar', baz => 'bazoo', }; -walk sub { - ok $Data::Walk::type, 'HASH'; - ok $Data::Walk::container, $data; -}, $data; + +Data::Walk::walk +{ + wanted => sub { + if ($Data::Walk::depth == 1) { + ok $Data::Walk::type, undef; + ok $Data::Walk::container, undef; + } elsif ($Data::Walk::depth == 2) { + ok $Data::Walk::type, 'HASH'; + ok $Data::Walk::container, $data; + } + }, + bydepth => 1 + }, $data; +Data::Walk::walk +{ + wanted => sub { + if ($Data::Walk::depth == 1) { + ok $Data::Walk::type, undef; + ok $Data::Walk::container, undef; + } elsif ($Data::Walk::depth == 2) { + ok $Data::Walk::type, 'HASH'; + ok $Data::Walk::container, $data; + } + }, + bydepth => 0 + }, $data; +__END__ diff --git a/t/05bug-container-type-at-depth-one.t b/t/05bug-container-type-at-depth-one.t new file mode 100644 index 0000000..027aff0 --- /dev/null +++ b/t/05bug-container-type-at-depth-one.t @@ -0,0 +1,83 @@ +# Data::Walk - Traverse Perl data structures. +# Copyright (C) 2005-2016 Guido Flohr <guido.flohr@cantanea.com>, +# all rights reserved. + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published +# by the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +use strict; + +use Test; +use Data::Walk; + +BEGIN { + plan tests => 28; +} + +my $hash = { + foo => 'bar', + baz => 'bazoo', +}; + +my $arr = [ + "moo", + "foo", + 1 +]; + +walk sub { + if ($Data::Walk::depth == 1) { + #The top level has no container + ok $Data::Walk::type, undef; + #Hence no type for container + ok $Data::Walk::container, undef; + } + elsif ( $Data::Walk::depth == 2) { + ok $Data::Walk::type, q/HASH/; + ok $Data::Walk::container, $hash; + } +}, $hash; + + +walk sub { + if ($Data::Walk::depth == 1) { + #The top level has no container + ok $Data::Walk::type, undef; + #Hence no type for container + ok $Data::Walk::container, undef; + } + elsif ( $Data::Walk::depth == 2) { + ok $Data::Walk::type, q/ARRAY/; + ok $Data::Walk::container, $arr; + } +}, $arr; + +walk sub { + if ($Data::Walk::depth == 1) { + #The top level has no container + ok $Data::Walk::type, undef; + #Hence no type for container + ok $Data::Walk::container, undef; + } +}, $hash, $arr; + +walk sub { + if ($Data::Walk::depth == 1) { + #The top level has no container + ok $Data::Walk::type, undef; + #Hence no type for container + ok $Data::Walk::container, undef; + } +}, 1, $hash, $arr;