Last active
September 12, 2015 03:50
-
-
Save zostay/13a073e62520b1041ecb to your computer and use it in GitHub Desktop.
Weird Iteration/Switch Bug
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
Okay, so I am at a loss so far as to what is happening here, but something | |
broke. | |
In Template::Anti, the node-set.t test is failing: | |
t/node-set.t ........... | |
ok 1 - text works | |
ok 2 - attrib one works | |
ok 3 - attrib two works | |
ok 4 - attrib three works | |
not ok 5 - | |
# Failed test at t/node-set.t line 43 | |
# expected: '<root><one/></root>' | |
# got: '<root><one/><two/><three/></root>' | |
not ok 6 - | |
# Failed test at t/node-set.t line 53 | |
# expected: '<root><one href="http://example.com/vader">Vader</one><one href="http://example.com/sidious">Sidious</one></root>' | |
# got: '<root><one href="http://example.com/vader">Vader</one><two/><three/><one href="http://example.com/sidious">Sidious</one></root>' | |
ok 7 - modifies original | |
1..7 | |
# Looks like you failed 2 tests of 7 | |
Dubious, test returned 2 (wstat 512, 0x200) | |
Failed 2/7 subtests | |
(See https://travis-ci.org/zostay/Template-Anti#L1104 for the original.) | |
This is failing because the truncate() method in NodeSet.pm6 is failing to | |
remove <two/> and <three/> from the DOM as is expected. The code for that looks | |
like this: | |
method truncate(Int $keep = 0) { | |
for @!nodes -> $node { | |
my $kept = 0; | |
if $keep == 0 { | |
$node.nodes = (); | |
} | |
else { | |
for $node.nodes { | |
when XML::Element { .remove if $kept++ >= $keep } | |
when XML::Node { .remove } | |
default { } | |
} | |
} | |
} | |
self | |
} | |
(See | |
https://github.com/zostay/Template-Anti/blob/master/lib/Template/Anti/NodeSet.pm6#L177 | |
for the original.) | |
The problem is that when it runs the innter loop (for $node.nodes), the block | |
for the `when XML::Element condition` is not being run even though there are | |
XML::Element nodes present. They are not falling into the XML::Node branch | |
either (obviously, since they would be removed if there were). | |
However, changing the for-loop like this instead fixes the problem: | |
my @nodes = $node.nodes; | |
for @nodes { | |
The question is why? Is there something wrong with using $node.nodes like this | |
or is something wrong with Rakudo? Or have I overlooked something else I have | |
done wrong here? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For some reason I was expecting (and pre-GLR, this assumption seems to have held true) that the for-loop iterated over a copy of the array. I was also under the impression that Perl 5's for-loop did the same. However, this is not true. When items in the array are deleted using .remove, some elements where being skipped during iteration.
Compare:
to:
The latter was basically what I was expecting to happen.