File: tmstd/treeable.rb

Overview
Module Structure
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: TmStd#8
  module: Treeable#10
has properties
method: each_descendant / 2 #11
method: __each_descendant__ / 3 #33
method: descendants / 1 #54
method: descendant_any? / 1 #63
method: descendant_all? / 1 #72
method: print_tree / 2 #81
method: __print_tree__ / 7 #127
method: __print_tree_indent__ / 1 #193
method: __print_tree_enter__ / 1 #201

Code

   1  # $Id: treeable.rb,v 1.4 2012/04/17 02:49:40 machan Exp $
   2 
   3  require 'enumerator'
   4 
   5  require 'tmdoc/tmstd/assertion'
   6 
   7 
   8  module TmStd
   9 
  10  module Treeable
  11      def each_descendant(selector = nil, &block)
  12          Assertion.opt_kind_of   selector,   Proc
  13          Assertion.kind_of       block,      Proc
  14 
  15          if selector
  16              for child in self.children
  17                  if selector.call(child)
  18                      yield child
  19                      __each_descendant__(child, selector, &block)
  20                  end
  21              end
  22          else
  23              for child in self.children
  24                  yield child
  25                  __each_descendant__(child, selector, &block)
  26              end
  27          end
  28 
  29          nil
  30      end
  31 
  32 
  33      def __each_descendant__(child, selector = nil, &block)
  34          Assertion.opt_kind_of   selector,   Proc
  35          Assertion.kind_of       block,      Proc
  36 
  37          if selector
  38              child.each_descendant do |grand_child|
  39                  if selector.call(grand_child)
  40                      yield grand_child
  41                  end
  42              end
  43          else
  44              child.each_descendant do |grand_child|
  45                  yield grand_child
  46              end
  47          end
  48 
  49          nil
  50      end
  51      private :__each_descendant__
  52 
  53 
  54      def descendants(&selector)
  55          Assertion.opt_kind_of selector, Proc
  56 
  57          ds = self.to_enum(:each_descendant, selector).to_a
  58 
  59          Assertion.kind_of ds, Array
  60      end
  61 
  62 
  63      def descendant_any?(&selector)
  64          Assertion.kind_of selector, Proc
  65 
  66          result = self.to_enum(:each_descendant).any?(&selector)
  67 
  68          Assertion.boolean result
  69      end
  70 
  71 
  72      def descendant_all?(&selector)
  73          Assertion.kind_of selector, Proc
  74 
  75          result = self.to_enum(:each_descendant).all?(&selector)
  76 
  77          Assertion.boolean result
  78      end
  79 
  80 
  81      def print_tree(io, opts = {})
  82          Assertion.kind_of opts, Hash
  83 
  84          in_verbatim = false
  85          rejector    = nil
  86          selector    = nil
  87          do_sort     = false
  88          comparator  = nil
  89 
  90          for key, val in opts
  91              Assertion.kind_of key, Symbol
  92 
  93              case key
  94              when :in_verbatim
  95                  ASSERT.boolean val
  96 
  97                  in_verbatim = val
  98              when :rejector
  99                  Assertion.kind_of val, Proc
 100 
 101                  rejector = val
 102              when :selector
 103                  Assertion.kind_of val, Proc
 104 
 105                  selector = val
 106              when :do_sort
 107                  ASSERT.boolean val
 108 
 109                  do_sort = val
 110              when :comparator
 111                  Assertion.kind_of val, Proc
 112 
 113                  comparator = val
 114              else
 115                  Assertion.abort "Unknown option: %s", key
 116              end
 117          end
 118 
 119          __print_tree__(
 120              io, 0, in_verbatim, rejector, selector, do_sort, comparator
 121          )
 122 
 123          nil
 124      end
 125 
 126 
 127      def __print_tree__(
 128          io, depth, in_verbatim, rejector, selector, do_sort, comparator
 129      )
 130          Assertion.kind_of       depth,          Integer
 131          Assertion.boolean       in_verbatim
 132          Assertion.opt_kind_of   rejector,       Proc
 133          Assertion.opt_kind_of   selector,       Proc
 134          Assertion.boolean       do_sort
 135          Assertion.opt_kind_of   comparator,     Proc
 136 
 137          selected    =
 138              if rejector || selector
 139                  self.children.select { |child|
 140                      rejector_result =
 141                          if rejector
 142                              ! rejector.call(child)
 143                          else
 144                              true
 145                          end
 146 
 147                      if rejector_result
 148                          if selector
 149                              selector.call(child)
 150                          else
 151                              true
 152                          end
 153                      else
 154                          false
 155                      end
 156                  }
 157              else
 158                  self.children
 159              end
 160          sorted      =
 161              if do_sort
 162                  if comparator
 163                      selected.sort_by(&comparator)
 164                  else
 165                      selected.sort_by { |elem| elem.to_s }
 166                  end
 167              else
 168                  selected
 169              end
 170 
 171          (0 .. depth).each do
 172              __print_tree_indent__(io)
 173          end
 174 
 175          __print_tree_enter__(io)
 176 
 177          for child in sorted
 178              child.__print_tree__(
 179                  io,
 180                  depth + 1,
 181                  in_verbatim,
 182                  rejector,
 183                  selector,
 184                  do_sort,
 185                  comparator
 186              )
 187          end
 188 
 189          nil
 190      end
 191 
 192 
 193      def __print_tree_indent__(io)
 194          io << '| '
 195 
 196          nil
 197      end
 198      private :__print_tree_indent__
 199 
 200 
 201      def __print_tree_enter__(io)
 202          io << self.to_s << "\n"
 203 
 204          nil
 205      end
 206      private :__print_tree_enter__
 207  end
 208 
 209  end # TmStd