rubytree 0.8.2 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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