File: tmstd/lsm/collection/sequence.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: TmStd#7
  module: Lsm#9
  module: Collection#11
  module: Sequence#13
  class: Abstract#15
inherits from
  Abstract ( TmStd::Lsm::Collection )
has properties
attribute: lsm_elements [R] #16
alias: to_a lsm_elements #17
alias: length size #18
method: initialize / 1 #21
method: dup #35
method: first #42
method: last #47
method: include? / 1 #52
method: to_s / 2 #61
method: join / 1 #68
method: each / 1 #77
method: map_with_index / 1 #84
method: append / 1 #94
method: + / 1 #117
method: << / 1 #136
alias: add << #146
alias: push << #157
method: pop #172
method: __at__ / 1 #188
  module: Mutable#201
has properties
method: add! / 1 #202
method: push! / 1 #211
method: pop! #220
  module: Equalable#229
has properties
method: hash #230
method: == / 1 #235
method: eql? / 1 #240
method: freeze_equality! #263
  module: Comparable#280
includes
  Comparable ( Builtin-Module )
has properties
method: <=> / 1 #284
  class: SeqOfString#318
inherits from
  Abstract ( TmStd::Lsm::Collection::Sequence )
has properties
constant: LSM_ELEMENT_CLASS #319

Code

   1  # $Id: sequence.rb,v 1.7 2011/12/09 09:08:26 machan Exp $
   2 
   3  require 'tmdoc/tmstd/assertion'
   4  require 'tmdoc/tmstd/lsm/abstraction'
   5 
   6 
   7  module TmStd
   8 
   9  module Lsm
  10 
  11  module Collection
  12 
  13  module Sequence
  14 
  15  class Abstract < Collection::Abstract
  16      attr_reader :lsm_elements
  17      alias       to_a        lsm_elements
  18      alias       length      size
  19 
  20 
  21      def initialize(elements = [])
  22          Assertion.kind_of elements, Array
  23 
  24          unless Assertion.disable?
  25              elem_class = lsm_element_class
  26              for element in elements
  27                  Assertion.kind_of element, elem_class
  28              end
  29          end
  30 
  31          @lsm_elements = elements
  32      end
  33 
  34 
  35      def dup
  36          new_seq = self.class.new @lsm_elements.dup
  37 
  38          Assertion.kind_of new_seq, self.class
  39      end
  40 
  41 
  42      def first
  43          Assertion.kind_of @lsm_elements.first, lsm_element_class
  44      end
  45 
  46 
  47      def last
  48          Assertion.kind_of @lsm_elements.last, lsm_element_class
  49      end
  50 
  51 
  52      def include?(element)
  53          Assertion.kind_of element, lsm_element_class
  54 
  55          result = @lsm_elements.include? element
  56 
  57          Assertion.boolean result
  58      end
  59 
  60 
  61      def to_s(sep = ', ')
  62          str = '[' + self.join(sep) + ']'
  63 
  64          Assertion.kind_of str, String
  65      end
  66 
  67 
  68      def join(sep)
  69          Assertion.kind_of sep, String
  70 
  71          str = @lsm_elements.map { |element| element.to_s }.join(sep)
  72 
  73          Assertion.kind_of str, String
  74      end
  75 
  76 
  77      def each(&block)
  78          @lsm_elements.each(&block)
  79 
  80          nil
  81      end
  82 
  83 
  84      def map_with_index(&block)
  85          array = []
  86          self.each_with_index do |element, index|
  87              array << block.call(element, index)
  88          end
  89 
  90          Assertion.kind_of array, Array
  91      end
  92 
  93 
  94      def append(others = [])
  95          Assertion.kind_of others, Array
  96 
  97          new_seq = self.class.new(
  98              self.to_a + (
  99                  others.map { |other| other.to_a }
 100              ).flatten
 101          )
 102 
 103          Assertion.kind_of new_seq, self.class
 104      end
 105 
 106 
 107      # EXAMPLE
 108      #
 109      #    seq = MySequence.new(['A', 'B', 'C'])
 110      #
 111      #    seq + MySequence.new(['X', 'Y', 'Z'])
 112      #    => ['A', 'B', 'C', 'X', 'Y', 'Z']
 113      #
 114      #    seq
 115      #    => ['A', 'B', 'C']        (* No Side-effect!! *)
 116      #
 117      def +(other)
 118          Assertion.kind_of other, Sequence::Abstract
 119 
 120          new_seq = self.class.new(@lsm_elements + other.to_a)
 121 
 122          Assertion.kind_of new_seq, self.class
 123      end
 124 
 125 
 126      # EXAMPLE
 127      #
 128      #    seq = MySequence.new(['A', 'B', 'C'])
 129      #
 130      #    seq << 'X'
 131      #    => ['A', 'B', 'C', 'X']
 132      #
 133      #    seq
 134      #    => ['A', 'B', 'C']        (* No Side-effect!! *)
 135      #
 136      def <<(element)
 137          Assertion.kind_of element, lsm_element_class
 138 
 139          new_elements = @lsm_elements.dup
 140          new_elements.push element
 141 
 142          new_seq = self.class.new new_elements
 143 
 144          Assertion.kind_of new_seq, self.class
 145      end
 146      alias add   <<
 147 
 148      # EXAMPLE
 149      #
 150      #   stack = MyStack.new(['A', 'B'])
 151      #
 152      #   stack.push('C')
 153      #   => ['A', 'B', 'C']
 154      #
 155      #   stack
 156      #   => ['A', 'B']        (* No Side-effect!! *)
 157      alias push  <<
 158 
 159 
 160      # EXAMPLE
 161      #
 162      #    stack = MyStack.new(['A', 'B', 'C'])
 163      #
 164      #    stack.pop
 165      #    => [['A', 'B'], 'C']
 166      #
 167      #    poped_stack, poped_elem = stack.pop
 168      #    => [['A', 'B'], 'C']
 169      #
 170      #    stack
 171      #    => ['A', 'B', 'C']      (* No Side-effect!! *)
 172      def pop
 173          pair =
 174              case @lsm_elements.size
 175              when 0
 176                  [self.class.new,                        nil]
 177              when 1
 178                  [self.class.new,                        @lsm_elements[0]]
 179              else
 180                  [self.class.new(@lsm_elements[0..-2]),  @lsm_elements[-1]]
 181              end
 182 
 183              # The poped element is a instance of lsm_element_class or nil.
 184          Assertion.tuple_of pair, [self.class, Object]
 185      end
 186 
 187 
 188      def __at__(index)
 189          Assertion.kind_of index, Integer
 190 
 191          Assertion.assert(0 <= index && index < @lsm_elements.length,
 192              "Out of range, index = %d", index
 193          )
 194 
 195          Assertion.opt_kind_of @lsm_elements[index], lsm_element_class
 196      end
 197  end
 198 
 199 
 200 
 201  module Mutable
 202      def add!(element)
 203          Assertion.kind_of element, lsm_element_class
 204 
 205          @lsm_elements.push element
 206 
 207          nil
 208      end
 209 
 210 
 211      def push!(element)
 212          Assertion.kind_of element, lsm_element_class
 213 
 214          @lsm_elements.push element
 215 
 216          nil
 217      end
 218 
 219 
 220      def pop!
 221          poped_elem = @lsm_elements.pop
 222 
 223          Assertion.kind_of poped_elem, lsm_element_class
 224      end
 225  end
 226 
 227 
 228 
 229  module Equalable
 230      def hash
 231          Assertion.kind_of self.to_s.hash, Integer
 232      end
 233 
 234 
 235      def ==(other)
 236          Assertion.boolean self.eql?(other)
 237      end
 238 
 239 
 240      def eql?(other)
 241          unless other.kind_of?(self.class)
 242              return false
 243          end
 244 
 245          if self.empty? && other.empty?
 246              return true
 247          end
 248 
 249          if self.length != other.length
 250              return false
 251          end
 252 
 253          self.each_with_index do |elem, i|
 254              if elem != other.__at__(i)
 255                  return false
 256              end
 257          end
 258 
 259          true
 260      end
 261 
 262 
 263      def freeze_equality!
 264          for element in @lsm_elements
 265              case element
 266              when String, Integer
 267                  element.freeze
 268              else
 269                  element.freeze_equality!
 270              end
 271          end
 272          @lsm_elements.freeze
 273 
 274          nil
 275      end
 276  end
 277 
 278 
 279 
 280  module Comparable
 281      include ::Comparable
 282 
 283 
 284      def <=>(other)
 285          Assertion.kind_of other, Abstract
 286 
 287          if self.empty? && other.empty?
 288              return 0
 289          end
 290 
 291          self_len    = self.length
 292          other_len   = other.length
 293          min_len     = self_len < other_len ? self_len : other_len
 294 
 295          for i in 0..(min_len - 1)
 296              result = self.__at__(i) <=> other.__at__(i)
 297              if result != 0
 298                  return result
 299              end
 300          end
 301 
 302          if self_len == other_len
 303              0
 304          elsif self_len < other_len
 305              -1
 306          else
 307              1
 308          end
 309      end
 310  end
 311 
 312  end # TmStd::Lsm::Collection::Sequence
 313 
 314  end # TmStd::Lsm::Collection
 315 
 316 
 317 
 318  class SeqOfString < Collection::Sequence::Abstract
 319      LSM_ELEMENT_CLASS = String
 320  end
 321 
 322  end # TmStd::Lsm
 323 
 324  end # TmStd