Created
February 15, 2013 20:18
-
-
Save FranklinChen/4963218 to your computer and use it in GitHub Desktop.
Tree traversal in Ruby, a response to http://michaelfeathers.typepad.com/michael_feathers_blog/2013/02/sub-tree-selection-with-flattenselect.html
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
require 'minitest/autorun' | |
# Traverse in preorder | |
def tree_traverse(tree, &block) | |
if tree.is_a? Array and tree.length > 0 | |
yield tree | |
tree.each {|t| tree_traverse(t, &block) } | |
end | |
end | |
class TreeEnumerable | |
include Enumerable | |
def initialize(tree) | |
@tree = tree | |
end | |
def each | |
tree_traverse(@tree) {|t| yield t } | |
end | |
end | |
def sexp_select(tree, symbols) | |
TreeEnumerable.new(tree).find_all {|e| symbols.include? e[0] } | |
end | |
class TestTreeSelect < MiniTest::Unit::TestCase | |
def test_find_instance_variables | |
test_tree = [:program, [[:class, [:const_ref, [:@const, "A", [1, 6]]], nil, | |
[:bodystmt, [[:def, [:@ident, "a", [1, 13]], [:params, nil, nil, nil, nil, nil], | |
[:bodystmt, | |
[[:assign, | |
[:var_field, [:@ivar, "@a", [1, 16]]], | |
[:var_ref, [:@ivar, "@b", [1, 21]]]]], nil, nil, nil]]], nil, nil, nil]]]] | |
result = [[:@ivar, "@a", [1, 16]], [:@ivar, "@b", [1, 21]]] | |
assert_equal result, sexp_select(test_tree, [:@ivar]) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment