Last active
May 14, 2018 17:25
-
-
Save vyuh/c02c909ef8e0cb46121f9456dae2b715 to your computer and use it in GitHub Desktop.
Data::Walk Bug Report and Patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Subject: Top Level Object should not have a container | |
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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have moved Data-Walk to github: https://github.com/gflohr/Data-Walk
Do you want to create a pull request? That probably gives better documentation. Otherwise, I can also jsut apply your patch.