lib/sycamore/tree.rb in sycamore-0.3.0 vs lib/sycamore/tree.rb in sycamore-0.3.1

- old
+ new

@@ -63,13 +63,20 @@ ## # Creates a new empty Tree. # def initialize - @data = Hash.new end + protected def data + @data ||= Hash.new + end + + protected def clear_data + @data = nil + end + ## # Creates a new Tree and initializes it with the given data. # # @param (see #add) # @return [Tree] @@ -216,42 +223,42 @@ end alias << add protected def add_node(node) - @data[node] ||= Nothing + data[node] ||= Nothing self end ## # @api private # def clear_child_of_node(node) - @data[valid_node! node] = Nothing + data[valid_node! node] = Nothing self end ## # @api private # def add_node_with_empty_child(node) valid_node! node - if @data.fetch(node, Nothing).nothing? - @data[node] = new_child(node) + if data.fetch(node, Nothing).nothing? + data[node] = new_child(node) end self end private def add_child(node, children) return add_node(node) if Nothing.like?(children) add_node_with_empty_child(node) - @data[node] << children + data[node] << children self end private def add_tree(tree) @@ -327,11 +334,11 @@ end alias >> delete protected def delete_node(node) - @data.delete(node) + data.delete(node) self end protected def delete_tree(tree) @@ -489,11 +496,11 @@ # tree.size # => 3 # tree.clear # tree.size # => 0 # def clear - @data.clear + data.clear self end ## @@ -507,11 +514,11 @@ # tree.to_h # => {foo: {bar: []}} # tree.compact # tree.to_h # => {foo: :bar} # def compact - @data.each do |node, child| case + data.each do |node, child| case when child.nothing? then next when child.empty? then clear_child_of_node(node) else child.compact end end @@ -533,11 +540,11 @@ # tree = Tree[foo: [:bar, :baz]] # tree.nodes # => [:foo] # tree[:foo].nodes # => [:bar, :baz] # def nodes - @data.keys + data.keys end alias keys nodes # Hash compatibility @@ -603,11 +610,11 @@ # @todo Should we differentiate the case of a leaf and a not present node? How? # def child_of(node) valid_node! node - Nothing.like?(child = @data[node]) ? Absence.at(self, node) : child + Nothing.like?(child = data[node]) ? Absence.at(self, node) : child end ## # The child tree of a node at a path. # @@ -682,11 +689,11 @@ # def fetch(node, *default, &block) return fetch_path(node, *default, &block) if node.is_a? Path valid_node! node - child = @data.fetch(node, *default, &block) + child = data.fetch(node, *default, &block) if child.equal? Nothing child = case when block_given? then yield when !default.empty? then default.first else raise ChildError, "node #{node.inspect} has no child tree" @@ -752,11 +759,11 @@ # > b # def each_node(&block) return enum_for(__callee__) unless block_given? - @data.each_key(&block) + data.each_key(&block) self end alias each_key each_node # Hash compatibility @@ -781,11 +788,11 @@ # > b => #<Tree: Nothing> # def each_pair(&block) return enum_for(__callee__) unless block_given? - @data.each_pair(&block) + data.each_pair(&block) self end alias each each_pair @@ -868,11 +875,11 @@ # Tree[1 => 2].include_node? Sycamore::Path[1,2] # => true # def include_node?(node) return include_path?(node) if node.is_a? Path - @data.include?(node) + data.include?(node) end alias member? include_node? # Hash compatibility alias has_key? include_node? # Hash compatibility alias key? include_node? # Hash compatibility @@ -952,11 +959,11 @@ # tree.delete("a") # tree.size # => 3 # tree["e"].size # => 2 # def size - @data.size + data.size end ## # The number of {#nodes nodes} in this tree and all of their children. # @@ -969,11 +976,11 @@ # tree.total_size # => 7 # tree["e"].total_size # => 2 # def total_size total = size - @data.each { |_, child| total += child.total_size } + data.each { |_, child| total += child.total_size } total end alias tsize total_size @@ -999,11 +1006,11 @@ # @example # Tree.new.empty? # => true # Tree[a: 1].empty? # => false # def empty? - @data.empty? + data.empty? end alias blank? empty? ## @@ -1144,11 +1151,11 @@ # A hash code of this tree. # # @return [Fixnum] # def hash - @data.hash ^ self.class.hash + data.hash ^ self.class.hash end ## # Checks if this tree has the same content as another tree. # @@ -1163,11 +1170,11 @@ # tree1.eql? tree2 # => false # tree1.eql? tree3 # => true # tree1.eql? tree4 # => false # def eql?(other) - (other.instance_of?(self.class) and @data.eql?(other.data)) or + (other.instance_of?(self.class) and data.eql?(other.data)) or (other.instance_of?(Absence) and other.eql?(self)) end ## # Checks if this tree has the same content as another tree, but ignores empty child trees. @@ -1337,11 +1344,11 @@ return {} if empty? # not the nicest, but fastest way to inject on hashes, as noted here: # http://stackoverflow.com/questions/3230863/ruby-rails-inject-on-hashes-good-style hash = {} - @data.each do |node, child| + data.each do |node, child| hash[node] = child.to_native_object(*args) end hash end @@ -1442,20 +1449,20 @@ ## # Clones the whole tree. # def initialize_clone(other) super - @data = Hash.new + clear_data add other end ## # Deep freezes the whole tree. # # @see http://ruby-doc.org/core/Object.html#method-i-freeze # def freeze - @data.freeze + data.freeze each { |_, child| child.freeze } super end end # Tree