rubytree 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rubytree.rb ADDED
@@ -0,0 +1,41 @@
1
+ # rubytree.rb - This file is part of the RubyTree package.
2
+ #
3
+
4
+ # = rubytree.rb - Generic implementation of an N-ary tree data structure.
5
+ #
6
+ # This file provides an alternative mechanism to require 'tree.rb', in case
7
+ # there is a conflict with another gem or Ruby package.
8
+ #
9
+ # Author:: Anupam Sengupta (anupamsg@gmail.com)
10
+ #
11
+ # Copyright (c) 2012 Anupam Sengupta
12
+ #
13
+ # All rights reserved.
14
+ #
15
+ # Redistribution and use in source and binary forms, with or without modification,
16
+ # are permitted provided that the following conditions are met:
17
+ #
18
+ # - Redistributions of source code must retain the above copyright notice, this
19
+ # list of conditions and the following disclaimer.
20
+ #
21
+ # - Redistributions in binary form must reproduce the above copyright notice, this
22
+ # list of conditions and the following disclaimer in the documentation and/or
23
+ # other materials provided with the distribution.
24
+ #
25
+ # - Neither the name of the organization nor the names of its contributors may
26
+ # be used to endorse or promote products derived from this software without
27
+ # specific prior written permission.
28
+ #
29
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
33
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
36
+ # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
+ #
40
+
41
+ require "tree.rb"
data/lib/tree.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # tree.rb - This file is part of the RubyTree package.
2
2
  #
3
- # $Revision$ by $Author$ on $Date$
4
- #
5
3
  # = tree.rb - Generic implementation of an N-ary tree data structure.
6
4
  #
7
5
  # Provides a generic tree data structure with ability to
@@ -11,7 +9,7 @@
11
9
  # Author:: Anupam Sengupta (anupamsg@gmail.com)
12
10
  #
13
11
 
14
- # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011 Anupam Sengupta
12
+ # Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Anupam Sengupta
15
13
  #
16
14
  # All rights reserved.
17
15
  #
@@ -41,37 +39,44 @@
41
39
  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
40
  #
43
41
 
42
+ require 'tree/tree_deps'
43
+ require 'tree/version'
44
+
44
45
  # This module provides a TreeNode class which is the primary class for representing
45
46
  # nodes in the tree.
46
47
  #
47
48
  # This module also acts as the namespace for all classes in the RubyTree package.
48
49
  module Tree
49
50
 
50
- # Rubytree Package Version
51
- VERSION = '0.8.2'
52
-
53
51
  # == TreeNode Class Description
54
52
  #
55
- # This class models the nodes for an *N-ary* tree data structue. The nodes are *named*
56
- # and have a place-holder for the node data (i.e., _content_ of the node). The node
57
- # names are required to be *unique* within the tree.
53
+ # This class models the nodes for an *N-ary* tree data structue. The
54
+ # nodes are *named* and have a place-holder for the node data (i.e.,
55
+ # _content_ of the node). The node names are required to be *unique*
56
+ # within the tree (as the name is implicitly used as an _ID_ within
57
+ # the data structure).
58
58
  #
59
- # The node's _content_ is *not* required to be unique across different nodes in the tree, and
60
- # can be +nil+ as well.
59
+ # The node's _content_ is *not* required to be unique across
60
+ # different nodes in the tree, and can be +nil+ as well.
61
61
  #
62
- # The class provides various methods to navigate the tree, traverse the structure,
63
- # modify contents of the node, change position of the node in the tree,
64
- # and to make structural changes to the tree.
62
+ # The class provides various methods to navigate the tree, traverse
63
+ # the structure, modify contents of the node, change position of the
64
+ # node in the tree, and to make structural changes to the tree.
65
65
  #
66
- # A node can have any number of *child* nodes attached to it and hence can be used to create N-ary trees.
67
- # Access to the child nodes can be made in order (with the conventional left to right access), or
68
- # randomly.
66
+ # A node can have any number of *child* nodes attached to it and
67
+ # hence can be used to create N-ary trees. Access to the child
68
+ # nodes can be made in order (with the conventional left to right
69
+ # access), or randomly.
69
70
  #
70
- # The node also provides direct access to its *parent* node as well as other superior parents in the path to
71
- # root of the tree. In addition, a node can also access its *sibling* nodes, if present.
71
+ # The node also provides direct access to its *parent* node as well
72
+ # as other superior parents in the path to root of the tree. In
73
+ # addition, a node can also access its *sibling* nodes, if present.
72
74
  #
73
- # Note that while this implementation does not _explicitly_ support directed graphs, the class itself makes
74
- # no restrictions on associating a node's *content* with multiple nodes in the tree.
75
+ # Note that while this implementation does not _explicitly_ support
76
+ # directed graphs, the class itself makes no restrictions on
77
+ # associating a node's *content* with multiple nodes in the tree.
78
+ # However, having duplicate nodes within the structure is likely to
79
+ # cause unpredictable behavior.
75
80
  #
76
81
  #
77
82
  # == Example
@@ -126,28 +131,62 @@ module Tree
126
131
  class TreeNode
127
132
  include Enumerable
128
133
 
134
+ # @!attribute [r] name
135
+ #
129
136
  # Name of this node. Expected to be unique within the tree.
137
+ #
138
+ # Note that the name attribute really functions as an *ID* within
139
+ # the tree structure, and hence the uniqueness constraint is
140
+ # required.
141
+ #
142
+ # This may be changed in the future, but for now it is best to
143
+ # retain unique names within the tree structure, and use the
144
+ # +content+ attribute for any non-unique node requirements.
145
+ #
146
+ # @see content
130
147
  attr_reader :name
131
148
 
132
- # Content of this node. Can be +nil+.
149
+ # @!attribute [rw] content
150
+ #
151
+ # Content of this node. Can be +nil+. Note that there is no
152
+ # uniqueness constraint related to this attribute.
153
+ #
154
+ # @see name
133
155
  attr_accessor :content
134
156
 
157
+ # @!attribute [r] parent
158
+ #
135
159
  # Parent of this node. Will be +nil+ for a root node.
136
160
  attr_reader :parent
137
161
 
162
+ # @!group Node Creation
163
+
138
164
  # Creates a new node with a name and optional content.
139
165
  # The node name is expected to be unique within the tree.
140
166
  #
141
167
  # The content can be of any type, and defaults to +nil+.
142
168
  #
143
- # @param [Object] name Name of the node. Usual usage is to pass a String.
169
+ # @param [Object] name Name of the node. Conventional usage is to pass a String
170
+ # (Integer names may cause *surprises*)
144
171
  # @param [Object] content Content of the node.
145
172
  #
146
173
  # @raise [ArgumentError] Raised if the node name is empty.
174
+ #
175
+ # @note If the name is an +Integer+, then the semantics of +TreeNode[]+ can
176
+ # be surprising, as an +Integer+ parameter to that method normally acts
177
+ # as an index to the <em>children array</em>, and follows the
178
+ # <em>zero-based</em> indexing convention.
179
+ #
180
+ # @see #[]
147
181
  def initialize(name, content = nil)
148
182
  raise ArgumentError, "Node name HAS to be provided!" if name == nil
149
183
  @name, @content = name, content
150
184
 
185
+ if name.kind_of?(Integer)
186
+ warn StandardWarning,
187
+ "Using integer as node name. Semantics of TreeNode[] may not be what you expect! #{name} #{content}"
188
+ end
189
+
151
190
  self.set_as_root!
152
191
  @children_hash = Hash.new
153
192
  @children = []
@@ -178,6 +217,8 @@ module Tree
178
217
  # @see Tree::TreeNode#detached_subtree_copy
179
218
  alias :dup :detached_subtree_copy
180
219
 
220
+ # @!endgroup
221
+
181
222
  # Returns string representation of the receiver node.
182
223
  # This method is primarily meant for debugging purposes.
183
224
  #
@@ -190,7 +231,8 @@ module Tree
190
231
  " Total Nodes: #{size()}"
191
232
  end
192
233
 
193
- # Returns an array of ancestors of the receiver node in reversed order
234
+ # @!attribute [r] parentage
235
+ # An array of ancestors of the receiver node in reversed order
194
236
  # (the first element is the immediate parent of the receiver).
195
237
  #
196
238
  # Returns +nil+ if the receiver is a root node.
@@ -219,6 +261,8 @@ module Tree
219
261
  @parent = parent
220
262
  end
221
263
 
264
+ # @!group Structure Modification
265
+
222
266
  # Convenience synonym for {Tree::TreeNode#add} method.
223
267
  #
224
268
  # This method allows an easy mechanism to add node hierarchies to the tree
@@ -267,7 +311,8 @@ module Tree
267
311
  #
268
312
  # @see #<<
269
313
  def add(child, at_index = -1)
270
- raise ArgumentError, "Attempting to add a nil node" unless child
314
+ raise ArgumentError, "Attempting to add a nil node" unless child # Only handles the immediate child scenario
315
+ raise ArgumentError, "Attempting add node to itself" if self == child
271
316
  raise "Child #{child.name} already added!" if @children_hash.has_key?(child.name)
272
317
 
273
318
  if insertion_range.include?(at_index)
@@ -281,8 +326,6 @@ module Tree
281
326
  return child
282
327
  end
283
328
 
284
-
285
-
286
329
  # Removes the specified child node from the receiver node.
287
330
  #
288
331
  # This method can also be used for *pruning* a sub-tree, in cases where the removed child node is
@@ -346,6 +389,8 @@ module Tree
346
389
  @parent = nil
347
390
  end
348
391
 
392
+ # @!endgroup
393
+
349
394
  # Returns +true+ if the receiver is a root node. Note that
350
395
  # orphaned children will also be reported as root nodes.
351
396
  #
@@ -373,10 +418,13 @@ module Tree
373
418
  !has_children?
374
419
  end
375
420
 
376
- # Returns an array of all the immediate children of the receiver node. The child nodes are ordered
377
- # "left-to-right" in the returned array.
421
+ # @!attribute [rw] children
422
+ # An array of all the immediate children of the receiver
423
+ # node. The child nodes are ordered "left-to-right" in the
424
+ # returned array.
378
425
  #
379
- # If a block is given, yields each child node to the block traversing from left to right.
426
+ # If a block is given, yields each child node to the block
427
+ # traversing from left to right.
380
428
  #
381
429
  # @yield [child] Each child is passed to the block, if given
382
430
  # @yieldparam [Tree::TreeNode] child Each child node.
@@ -390,24 +438,26 @@ module Tree
390
438
  end
391
439
  end
392
440
 
393
- # Returns the first child of the receiver node.
394
- #
395
- # Will return +nil+ if no children are present.
441
+ # @!attribute [rw] first_child
442
+ # First child of the receiver node.
443
+ # Will be +nil+ if no children are present.
396
444
  #
397
445
  # @return [Tree::TreeNode] The first child, or +nil+ if none is present.
398
446
  def first_child
399
447
  children.first
400
448
  end
401
449
 
402
- # Returns the last child of the receiver node.
403
- #
404
- # Will return +nil+ if no children are present.
450
+ # @!attribute [rw] last_child
451
+ # Last child of the receiver node.
452
+ # Will be +nil+ if no children are present.
405
453
  #
406
454
  # @return [Tree::TreeNode] The last child, or +nil+ if none is present.
407
455
  def last_child
408
456
  children.last
409
457
  end
410
458
 
459
+ # @!group Tree Traversal
460
+
411
461
  # Traverses each node (including the receiver node) of the (sub)tree rooted at this node
412
462
  # by yielding the nodes to the specified block.
413
463
  #
@@ -467,55 +517,77 @@ module Tree
467
517
  # @see #each
468
518
  # @see #breadth_each
469
519
  def each_leaf &block
470
- self.each { |node| yield(node) if node.is_leaf? }
520
+ if block_given?
521
+ self.each { |node| yield(node) if node.is_leaf? }
522
+ else
523
+ self.select { |node| node.is_leaf?}
524
+ end
471
525
  end
472
526
 
473
527
  # Returns the requested node from the set of immediate children.
474
528
  #
475
- # If the argument is _numeric_, then the in-sequence array of children is accessed using
476
- # the argument as the *index* (zero-based).
529
+ # - If the +name+ argument is an _Integer_, then the in-sequence
530
+ # array of children is accessed using the argument as the
531
+ # *index* (zero-based). However, if the second _optional_
532
+ # +num_as_name+ argument is +true+, then the +name+ is used
533
+ # literally as a name, and *NOT* as an *index*
477
534
  #
478
- # If the argument is *NOT* _numeric_, then it is taken to be the *name* of the child node to be returned.
535
+ # - If the +name+ argument is *NOT* an _Integer_, then it is taken to
536
+ # be the *name* of the child node to be returned.
479
537
  #
480
- # An ArgumentError exception is raised if neither name nor an index is provided.
538
+ # If a non-+Integer+ +name+ is passed, and the +num_as_name+
539
+ # parameter is also +true+, then a warning is thrown (as this is a
540
+ # redundant use of the +num_as_name+ flag.)
481
541
  #
482
- # @param [String|Number] name_or_index Name of the child, or its positional index in the array of child nodes.
542
+ # @param [String|Number] name_or_index Name of the child, or its
543
+ # positional index in the array of child nodes.
483
544
  #
484
- # @return [Tree::TreeNode] the requested child node. If the index in not in range, or the name is not
485
- # present, then a +nil+ is returned.
545
+ # @param [Boolean] num_as_name Whether to treat the +Integer+
546
+ # +name+ argument as an actual name, and *NOT* as an _index_ to
547
+ # the children array.
486
548
  #
487
- # @raise [ArgumentError] Raised if neither name nor index is provided.
549
+ # @return [Tree::TreeNode] the requested child node. If the index
550
+ # in not in range, or the name is not present, then a +nil+
551
+ # is returned.
552
+ #
553
+ # @note The use of +Integer+ names is allowed by using the optional +num_as_name+ flag.
554
+ #
555
+ # @raise [ArgumentError] Raised if the +name_or_index+ argument is +nil+.
488
556
  #
489
557
  # @see #add
490
- def [](name_or_index)
558
+ # @see #initialize
559
+ def [](name_or_index, num_as_name=false)
491
560
  raise ArgumentError, "Name_or_index needs to be provided!" if name_or_index == nil
492
561
 
493
- if name_or_index.kind_of?(Integer)
562
+ if name_or_index.kind_of?(Integer) and not num_as_name
494
563
  @children[name_or_index]
495
564
  else
565
+ if num_as_name and not name_or_index.kind_of?(Integer)
566
+ warn StandardWarning, "Redundant use of the `num_as_name` flag for non-integer node name"
567
+ end
496
568
  @children_hash[name_or_index]
497
569
  end
498
570
  end
499
571
 
500
- # Returns the total number of nodes in this (sub)tree, including the receiver node.
572
+ # @!endgroup
573
+
574
+ # @!attribute [r] size
575
+ # Total number of nodes in this (sub)tree, including the receiver node.
501
576
  #
502
577
  # Size of the tree is defined as:
503
578
  #
504
579
  # Size:: Total number nodes in the subtree including the receiver node.
505
580
  #
506
- # @return [Number] Total number of nodes in this (sub)tree.
581
+ # @return [Integer] Total number of nodes in this (sub)tree.
507
582
  def size
508
583
  @children.inject(1) {|sum, node| sum + node.size}
509
584
  end
510
585
 
511
586
  # Convenience synonym for {Tree::TreeNode#size}.
512
587
  #
513
- # @todo The semantic of length is probably unclear. Should return the node depth instead
514
- # to reflect the path length.
515
- #
516
588
  # @deprecated This method name is ambiguous and may be removed. Use TreeNode#size instead.
517
589
  #
518
- # @return [Number] The total number of nodes in this (sub)tree.
590
+ # @return [Integer] The total number of nodes in this (sub)tree.
519
591
  # @see #size
520
592
  def length
521
593
  size()
@@ -523,7 +595,7 @@ module Tree
523
595
 
524
596
  # Pretty prints the (sub)tree rooted at the receiver node.
525
597
  #
526
- # @param [Number] level The indentation level (4 spaces) to start with.
598
+ # @param [Integer] level The indentation level (4 spaces) to start with.
527
599
  def print_tree(level = 0)
528
600
  if is_root?
529
601
  print "*"
@@ -540,11 +612,9 @@ module Tree
540
612
  children { |child| child.print_tree(level + 1)}
541
613
  end
542
614
 
543
- # Returns root node for the (sub)tree to which the receiver node belongs.
544
- #
545
- # Note that a root node's root is itself (*beware* of any loop construct that may become infinite!)
546
- #
547
- # @todo We should perhaps return nil as root's root.
615
+ # @!attribute [rw] root
616
+ # root node for the (sub)tree to which the receiver node belongs.
617
+ # A root node's root is itself.
548
618
  #
549
619
  # @return [Tree::TreeNode] Root of the (sub)tree.
550
620
  def root
@@ -553,15 +623,13 @@ module Tree
553
623
  root
554
624
  end
555
625
 
556
- # Returns the first sibling of the receiver node. If this is the root node, then returns
626
+ # @!attribute [rw] first_sibling
627
+ # First sibling of the receiver node. If this is the root node, then returns
557
628
  # itself.
558
629
  #
559
630
  # 'First' sibling is defined as follows:
560
631
  # First sibling:: The left-most child of the receiver's parent, which may be the receiver itself
561
632
  #
562
- # @todo Fix the inconsistency of returning root as its first sibling, and returning
563
- # a +nil+ array for siblings of the node.
564
- #
565
633
  # @return [Tree::TreeNode] The first sibling node.
566
634
  #
567
635
  # @see #is_first_sibling?
@@ -580,15 +648,13 @@ module Tree
580
648
  first_sibling == self
581
649
  end
582
650
 
583
- # Returns the last sibling of the receiver node. If this is the root node, then returns
651
+ # @!attribute [rw] last_sibling
652
+ # Last sibling of the receiver node. If this is the root node, then returns
584
653
  # itself.
585
654
  #
586
655
  # 'Last' sibling is defined as follows:
587
656
  # Last sibling:: The right-most child of the receiver's parent, which may be the receiver itself
588
657
  #
589
- # @todo Fix the inconsistency of returning root as its last sibling, and returning
590
- # a +nil+ array for siblings of the node.
591
- #
592
658
  # @return [Tree::TreeNode] The last sibling node.
593
659
  #
594
660
  # @see #is_last_sibling?
@@ -607,16 +673,12 @@ module Tree
607
673
  last_sibling == self
608
674
  end
609
675
 
610
- # Returns an array of siblings for the receiver node. The receiver node is excluded.
676
+ # @!attribute [rw] siblings
677
+ # An array of siblings for the receiver node. The receiver node is excluded.
611
678
  #
612
679
  # If a block is provided, yields each of the sibling nodes to the block.
613
680
  # The root always has +nil+ siblings.
614
681
  #
615
- # @todo Fix the inconsistency of returning root as its own first/last sibling, and returning
616
- # a +nil+ array for siblings of the same root node.
617
- # @todo Also fix the inconsistency of returning +nil+ for a root node, and an empty array for nodes
618
- # which have no siblings.
619
- #
620
682
  # @yield [sibling] Each sibling is passed to the block.
621
683
  # @yieldparam [Tree::TreeNode] sibling Each sibling node.
622
684
  #
@@ -625,7 +687,7 @@ module Tree
625
687
  # @see #first_sibling
626
688
  # @see #last_sibling
627
689
  def siblings
628
- return nil if is_root?
690
+ return [] if is_root?
629
691
 
630
692
  if block_given?
631
693
  parent.children.each { |sibling| yield sibling if sibling != self }
@@ -647,7 +709,8 @@ module Tree
647
709
  is_root? ? true : parent.children.size == 1
648
710
  end
649
711
 
650
- # Returns the next sibling for the receiver node.
712
+ # @!attribute [rw] next_sibling
713
+ # Next sibling for the receiver node.
651
714
  # The 'next' node is defined as the node to right of the receiver node.
652
715
  #
653
716
  # Will return +nil+ if no subsequent node is present, or if the receiver is a root node.
@@ -663,7 +726,8 @@ module Tree
663
726
  parent.children.at(myidx + 1) if myidx
664
727
  end
665
728
 
666
- # Returns the previous sibling of the receiver node.
729
+ # @!attribute [rw] previous_sibling
730
+ # Previous sibling of the receiver node.
667
731
  # 'Previous' node is defined to be the node to left of the receiver node.
668
732
  #
669
733
  # Will return +nil+ if no predecessor node is present, or if the receiver is a root node.
@@ -685,7 +749,7 @@ module Tree
685
749
  #
686
750
  # @param [Tree::TreeNode] other The other node to compare against.
687
751
  #
688
- # @return [Number] +1 if this node is a 'successor', 0 if equal and -1 if this node is a 'predecessor'.
752
+ # @return [Integer] +1 if this node is a 'successor', 0 if equal and -1 if this node is a 'predecessor'.
689
753
  def <=>(other)
690
754
  return +1 if other == nil
691
755
  self.name <=> other.name
@@ -735,19 +799,18 @@ module Tree
735
799
  end
736
800
  end
737
801
 
738
- # Creates a JSON representation of this node including all it's children. This requires the JSON gem to be
739
- # available, or else the operation fails with a warning message.
802
+ # Creates a JSON ready Hash for the #to_json method.
740
803
  #
741
- # @author Dirk Breuer (http://github.com/railsbros-dirk)
742
- # @since 0.7.0
804
+ # @author Eric Cline (https://github.com/escline)
805
+ # @since 0.8.3
743
806
  #
744
- # @return The JSON representation of this subtree.
807
+ # @return A hash based representation of the JSON
745
808
  #
746
- # @see Tree::TreeNode.json_create
747
- # @see http://flori.github.com/json
748
- def to_json(*a)
749
- begin
750
- require 'json'
809
+ # Rails uses JSON in ActiveSupport, and all Rails JSON encoding goes through as_json
810
+ #
811
+ # @see Tree::TreeNode.to_json
812
+ # @see http://stackoverflow.com/a/6880638/273808
813
+ def as_json(options = {})
751
814
 
752
815
  json_hash = {
753
816
  "name" => name,
@@ -759,11 +822,24 @@ module Tree
759
822
  json_hash["children"] = children
760
823
  end
761
824
 
762
- return json_hash.to_json
825
+ return json_hash
763
826
 
764
- rescue LoadError
765
- warn "The JSON gem couldn't be loaded. Due to this we cannot serialize the tree to a JSON representation"
766
- end
827
+ end
828
+
829
+ # Creates a JSON representation of this node including all it's children. This requires the JSON gem to be
830
+ # available, or else the operation fails with a warning message.
831
+ # Uses the Hash output of as_json method, defined above.
832
+ #
833
+ # @author Dirk Breuer (http://github.com/railsbros-dirk)
834
+ # @since 0.7.0
835
+ #
836
+ # @return The JSON representation of this subtree.
837
+ #
838
+ # @see Tree::TreeNode.json_create
839
+ # @see Tree::TreeNode.as_json
840
+ # @see http://flori.github.com/json
841
+ def to_json(*a)
842
+ as_json.to_json(*a)
767
843
  end
768
844
 
769
845
  # Helper method to create a Tree::TreeNode instance from the JSON hash representation. Note that this method should
@@ -783,35 +859,33 @@ module Tree
783
859
  # @see #to_json
784
860
  # @see http://flori.github.com/json
785
861
  def self.json_create(json_hash)
786
- begin
787
- require 'json'
788
862
 
789
- node = new(json_hash["name"], json_hash["content"])
863
+ node = new(json_hash["name"], json_hash["content"])
790
864
 
791
- json_hash["children"].each do |child|
792
- node << child
793
- end if json_hash["children"]
865
+ json_hash["children"].each do |child|
866
+ node << child
867
+ end if json_hash["children"]
868
+
869
+ return node
794
870
 
795
- return node
796
- rescue LoadError => e
797
- warn "The JSON gem couldn't be loaded. Due to this we cannot serialize the tree to a JSON representation."
798
- end
799
871
  end
800
872
 
801
- # Returns height of the (sub)tree from the receiver node. Height of a node is defined as:
873
+ # @!attribute [r] node_height
874
+ # Height of the (sub)tree from the receiver node. Height of a node is defined as:
802
875
  #
803
876
  # Height:: Length of the longest downward path to a leaf from the node.
804
877
  #
805
878
  # - Height from a root node is height of the entire tree.
806
879
  # - The height of a leaf node is zero.
807
880
  #
808
- # @return [Number] Height of the node.
881
+ # @return [Integer] Height of the node.
809
882
  def node_height
810
883
  return 0 if is_leaf?
811
884
  1 + @children.collect { |child| child.node_height }.max
812
885
  end
813
886
 
814
- # Returns depth of the receiver node in its tree. Depth of a node is defined as:
887
+ # @!attribute [r] node_depth
888
+ # Depth of the receiver node in its tree. Depth of a node is defined as:
815
889
  #
816
890
  # Depth:: Length of the node's path to its root. Depth of a root node is zero.
817
891
  #
@@ -820,7 +894,7 @@ module Tree
820
894
  #
821
895
  # 'level' is an alias for this method.
822
896
  #
823
- # @return [Number] Depth of this node.
897
+ # @return [Integer] Depth of this node.
824
898
  def node_depth
825
899
  return 0 if is_root?
826
900
  1 + parent.node_depth
@@ -838,74 +912,62 @@ module Tree
838
912
  # For correct and conventional behavior, please use {Tree::TreeNode#node_depth} and
839
913
  # {Tree::TreeNode#node_height} methods instead.
840
914
  #
841
- # @return [Number] depth of the node.
915
+ # @return [Integer] depth of the node.
842
916
  # @deprecated This method returns an incorrect value. Use the 'node_depth' method instead.
843
917
  #
844
918
  # @see #node_depth
845
919
  def depth
846
- begin
847
- require 'structured_warnings' # To enable a nice way of deprecating of the depth method.
848
- warn DeprecatedMethodWarning, 'This method is deprecated. Please use node_depth() or node_height() instead (bug # 22535)'
849
- rescue LoadError
850
- # Oh well. Will use the standard Kernel#warn. Behavior will be identical.
851
- warn 'Tree::TreeNode#depth() method is deprecated. Please use node_depth() or node_height() instead (bug # 22535)'
852
- end
920
+ warn DeprecatedMethodWarning, 'This method is deprecated. Please use node_depth() or node_height() instead (bug # 22535)'
853
921
 
854
922
  return 1 if is_leaf?
855
923
  1 + @children.collect { |child| child.depth }.max
856
924
  end
857
925
 
858
926
  # Allow the deprecated CamelCase method names. Display a warning.
927
+ # :nodoc:
859
928
  def method_missing(meth, *args, &blk)
860
929
  if self.respond_to?(new_method_name = underscore(meth))
861
- begin
862
- require 'structured_warnings' # To enable a nice way of deprecating of the invoked CamelCase method.
863
- warn DeprecatedMethodWarning, "The camelCased methods are deprecated. Please use #{new_method_name} instead of #{meth}"
864
-
865
- rescue LoadError
866
- # Oh well. Will use the standard Kernel#warn. Behavior will be identical.
867
- warn "Tree::TreeNode##{meth}() method is deprecated. Please use #{new_method_name} instead."
868
-
869
- ensure # Invoke the method now.
870
- return send(new_method_name, *args, &blk)
871
- end
872
-
930
+ warn DeprecatedMethodWarning, "The camelCased methods are deprecated. Please use #{new_method_name} instead of #{meth}"
931
+ return send(new_method_name, *args, &blk)
873
932
  else
874
933
  super
875
934
  end
876
935
  end
877
936
 
878
- # Returns breadth of the tree at the receiver node's level.
937
+ # @!attribute [r] breadth
938
+ # Breadth of the tree at the receiver node's level.
879
939
  # A single node without siblings has a breadth of 1.
880
940
  #
881
941
  # Breadth is defined to be:
882
942
  # Breadth:: Number of sibling nodes to this node + 1 (this node itself),
883
943
  # i.e., the number of children the parent of this node has.
884
944
  #
885
- # @return [Number] breadth of the node's level.
945
+ # @return [Integer] breadth of the node's level.
886
946
  def breadth
887
947
  is_root? ? 1 : parent.children.size
888
948
  end
889
949
 
890
- # Returns the incoming edge-count of the receiver node.
950
+ # @!attribute [r] in_degree
951
+ # The incoming edge-count of the receiver node.
891
952
  #
892
953
  # In-degree is defined as:
893
- # In-degree:: The number of edges arriving at the node (0 for root, 1 for all other nodes)
954
+ # In-degree:: Number of edges arriving at the node (0 for root, 1 for all other nodes)
894
955
  #
895
956
  # - In-degree = 0 for a root or orphaned node
896
957
  # - In-degree = 1 for a node which has a parent
897
958
  #
898
- # @return [Number] The in-degree of this node.
959
+ # @return [Integer] The in-degree of this node.
899
960
  def in_degree
900
961
  is_root? ? 0 : 1
901
962
  end
902
963
 
903
- # Returns the outgoing edge-count of the receiver node.
964
+ # @!attribute [r] out_degree
965
+ # The outgoing edge-count of the receiver node.
904
966
  #
905
967
  # Out-degree is defined as:
906
- # Out-degree:: The number of edges leaving the node (zero for leafs)
968
+ # Out-degree:: Number of edges leaving the node (zero for leafs)
907
969
  #
908
- # @return [Number] The out-degree of this node.
970
+ # @return [Integer] The out-degree of this node.
909
971
  def out_degree
910
972
  is_leaf? ? 0 : children.size
911
973
  end