3232module Tree
3333 module Utils
3434 # Provides structure-modification helpers for TreeNode.
35+ # rubocop:disable Metrics/ModuleLength
3536 module TreeStructureHandler
3637 # Convenience synonym for {Tree::TreeNode#add} method.
3738 def <<( child )
@@ -40,39 +41,12 @@ def <<(child)
4041
4142 # Adds the specified child node to this node.
4243 def add ( child , at_index = -1 )
43- # Only handles the immediate child scenario
44- raise ArgumentError , 'Attempting to add a nil node' unless child
45-
46- raise ArgumentError , 'Attempting add node to itself' if equal? ( child )
47-
48- raise ArgumentError , 'Attempting add root as a child' if child . equal? ( root )
49-
50- if ( ancestors = parentage ) && ancestors . include? ( child )
51- raise ArgumentError , 'Attempting add ancestor as a child'
52- end
53-
54- # Lazy man's unique test, won't test if children of child are unique in
55- # this tree too.
56- raise "Child #{ child . name } already added!" if @children_hash . include? ( child . name )
44+ validate_add_child! ( child )
45+ ensure_unique_child_name! ( child )
5746
5847 child . parent &.remove! child # Detach from the old parent
59-
60- if insertion_range . include? ( at_index )
61- @children . insert ( at_index , child )
62- else
63- message = [
64- 'Attempting to insert a child at a non-existent location' ,
65- "(#{ at_index } )" ,
66- 'when only positions from' ,
67- "#{ insertion_range . min } to #{ insertion_range . max } exist."
68- ] . join ( ' ' )
69- raise message
70- end
71-
72- @children_hash [ child . name ] = child
73- child . parent = self
74- invalidate_size_cache_upwards!
75- child
48+ insert_child_at! ( child , at_index )
49+ attach_child! ( child )
7650 end
7751
7852 # Return a range of valid insertion positions. Used in the #add method.
@@ -97,11 +71,9 @@ def rename(new_name)
9771
9872 # Renames the specified child node
9973 def rename_child ( old_name , new_name )
100- raise ArgumentError ,
101- "Invalid child name specified: #{ old_name } " unless @children_hash . key? ( old_name )
74+ raise ArgumentError , "Invalid child name specified: #{ old_name } " unless @children_hash . key? ( old_name )
10275
103- raise ArgumentError ,
104- "Child name already exists: #{ new_name } " if @children_hash . key? ( new_name )
76+ raise ArgumentError , "Child name already exists: #{ new_name } " if @children_hash . key? ( new_name )
10577
10678 @children_hash [ new_name ] = @children_hash . delete ( old_name )
10779 @children_hash [ new_name ] . name = new_name
@@ -170,25 +142,45 @@ def freeze_tree!
170142 each ( &:freeze )
171143 end
172144
173- def clear_root_cache!
174- @root_cache = nil
175- return unless @children
145+ def validate_add_child! ( child )
146+ raise ArgumentError , 'Attempting to add a nil node' unless child
147+ raise ArgumentError , 'Attempting add node to itself' if equal? ( child )
148+ raise ArgumentError , 'Attempting add root as a child' if child . equal? ( root )
176149
177- children_array . each do | child |
178- child &. __send__ ( :clear_root_cache! )
179- end
150+ return unless ( ancestors = parentage ) && ancestors . include? ( child )
151+
152+ raise ArgumentError , 'Attempting add ancestor as a child'
180153 end
181154
182- def invalidate_size_cache_upwards!
183- node = self
184- while node
185- node . instance_variable_set ( :@size , nil )
186- node = node . parent
187- end
155+ def ensure_unique_child_name! ( child )
156+ return unless @children_hash . include? ( child . name )
157+
158+ raise "Child #{ child . name } already added!"
159+ end
160+
161+ def insert_child_at! ( child , at_index )
162+ return @children . insert ( at_index , child ) if insertion_range . include? ( at_index )
163+
164+ message = [
165+ 'Attempting to insert a child at a non-existent location' ,
166+ "(#{ at_index } )" ,
167+ 'when only positions from' ,
168+ "#{ insertion_range . min } to #{ insertion_range . max } exist."
169+ ] . join ( ' ' )
170+ raise message
171+ end
172+
173+ def attach_child! ( child )
174+ @children_hash [ child . name ] = child
175+ child . parent = self
176+ invalidate_size_cache_upwards!
177+ child
188178 end
189179
190- private :insertion_range , :clear_root_cache! , :invalidate_size_cache_upwards!
180+ private :insertion_range , :validate_add_child! , :ensure_unique_child_name! ,
181+ :insert_child_at! , :attach_child!
191182 protected :parent= , :set_as_root!
192183 end
184+ # rubocop:enable Metrics/ModuleLength
193185 end
194186end
0 commit comments