tty 0.0.7 → 0.0.8

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.
Files changed (66) hide show
  1. data/.travis.yml +0 -1
  2. data/README.md +141 -23
  3. data/benchmarks/table.rb +5 -0
  4. data/lib/tty/logger.rb +71 -0
  5. data/lib/tty/support/equatable.rb +6 -2
  6. data/lib/tty/system/which.rb +41 -0
  7. data/lib/tty/system.rb +8 -0
  8. data/lib/tty/table/border/ascii.rb +15 -16
  9. data/lib/tty/table/border/null.rb +9 -4
  10. data/lib/tty/table/border/unicode.rb +15 -16
  11. data/lib/tty/table/border.rb +69 -9
  12. data/lib/tty/table/border_dsl.rb +247 -0
  13. data/lib/tty/table/border_options.rb +52 -0
  14. data/lib/tty/table/field.rb +101 -0
  15. data/lib/tty/table/header.rb +115 -0
  16. data/lib/tty/table/operation/alignment_set.rb +14 -10
  17. data/lib/tty/table/operation/truncation.rb +19 -13
  18. data/lib/tty/table/operation/wrapped.rb +20 -9
  19. data/lib/tty/table/operations.rb +69 -0
  20. data/lib/tty/table/renderer/basic.rb +35 -26
  21. data/lib/tty/table/renderer.rb +13 -1
  22. data/lib/tty/table/row.rb +174 -0
  23. data/lib/tty/table.rb +96 -21
  24. data/lib/tty/text/truncation.rb +1 -1
  25. data/lib/tty/vector.rb +8 -7
  26. data/lib/tty/version.rb +1 -1
  27. data/lib/tty.rb +21 -0
  28. data/spec/tty/logger/new_spec.rb +36 -0
  29. data/spec/tty/logger/valid_level_spec.rb +33 -0
  30. data/spec/tty/system/platform_spec.rb +8 -0
  31. data/spec/tty/system/which_spec.rb +41 -0
  32. data/spec/tty/table/access_spec.rb +12 -1
  33. data/spec/tty/table/add_row_spec.rb +28 -0
  34. data/spec/tty/table/border/new_spec.rb +9 -4
  35. data/spec/tty/table/border/null/rendering_spec.rb +39 -1
  36. data/spec/tty/table/border/options/from_spec.rb +39 -0
  37. data/spec/tty/table/border/options/new_spec.rb +15 -0
  38. data/spec/tty/table/border/style_spec.rb +70 -0
  39. data/spec/tty/table/border_spec.rb +107 -0
  40. data/spec/tty/table/each_with_index_spec.rb +30 -0
  41. data/spec/tty/table/field/equality_spec.rb +51 -0
  42. data/spec/tty/table/field/new_spec.rb +29 -0
  43. data/spec/tty/table/field/width_spec.rb +21 -0
  44. data/spec/tty/table/header/call_spec.rb +30 -0
  45. data/spec/tty/table/header/new_spec.rb +25 -0
  46. data/spec/tty/table/header/set_spec.rb +15 -0
  47. data/spec/tty/table/header/to_ary_spec.rb +14 -0
  48. data/spec/tty/table/header_spec.rb +14 -0
  49. data/spec/tty/table/operation/alignment_set/align_rows_spec.rb +8 -1
  50. data/spec/tty/table/operation/truncation/call_spec.rb +27 -0
  51. data/spec/tty/table/operation/wrapped/call_spec.rb +27 -0
  52. data/spec/tty/table/operations/new_spec.rb +32 -0
  53. data/spec/tty/table/options_spec.rb +17 -9
  54. data/spec/tty/table/renderer/basic/alignment_spec.rb +76 -29
  55. data/spec/tty/table/renderer/basic/separator_spec.rb +99 -0
  56. data/spec/tty/table/renderer_spec.rb +7 -1
  57. data/spec/tty/table/renders_with_spec.rb +35 -28
  58. data/spec/tty/table/rotate_spec.rb +1 -0
  59. data/spec/tty/table/row/access_spec.rb +25 -0
  60. data/spec/tty/table/row/call_spec.rb +41 -0
  61. data/spec/tty/table/row/data_spec.rb +26 -0
  62. data/spec/tty/table/row/equality_spec.rb +73 -0
  63. data/spec/tty/table/row/new_spec.rb +41 -0
  64. data/spec/tty/table/row/to_ary_spec.rb +14 -0
  65. data/spec/tty/text/truncation/truncate_spec.rb +6 -0
  66. metadata +72 -10
@@ -0,0 +1,69 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module TTY
4
+ class Table
5
+
6
+ # A class holding table field operations
7
+ class Operations
8
+
9
+ # The table
10
+ #
11
+ # @api private
12
+ attr_reader :table
13
+ private :table
14
+
15
+ # Initialize Operations
16
+ #
17
+ # @param [TTY::Table] table
18
+ # the table to perform operations on
19
+ #
20
+ # @return [Object]
21
+ #
22
+ # @api public
23
+ def initialize(table)
24
+ @table = table
25
+ end
26
+
27
+ # Available operations
28
+ #
29
+ # @return [Hash]
30
+ #
31
+ # @api public
32
+ def operations
33
+ @operations ||= Hash.new { |hash, key| hash[key] = [] }
34
+ end
35
+
36
+ # Add operation
37
+ #
38
+ # @param [Symbol] type
39
+ # the operation type
40
+ # @param [Object] object
41
+ # the callable object
42
+ #
43
+ # @return [Hash]
44
+ #
45
+ # @api public
46
+ def add_operation(type, object)
47
+ operations[type] << object
48
+ end
49
+
50
+ # Apply operations to a table row
51
+ #
52
+ # @param [Symbol] type
53
+ # the operation type
54
+ # @param [#to_ary, Row] row
55
+ # the row to apply operation to
56
+ # @param [Hash] options
57
+ # the options for the row
58
+ #
59
+ # @return [Hash]
60
+ #
61
+ # @api public
62
+ def run_operations(type, row, options={})
63
+ options.merge!(:column_widths => table.column_widths)
64
+ operations[type].each { |op| op.call(row, options) }
65
+ end
66
+
67
+ end # Operations
68
+ end # Table
69
+ end # TTY
@@ -8,10 +8,6 @@ module TTY
8
8
  class Basic
9
9
  extend TTY::Delegatable
10
10
 
11
- attr_reader :padding
12
-
13
- attr_reader :indent
14
-
15
11
  # Table to be rendered
16
12
  #
17
13
  # @return [TTY::Table]
@@ -19,7 +15,6 @@ module TTY
19
15
  # @api public
20
16
  attr_reader :table
21
17
 
22
-
23
18
  # Table border to be rendered
24
19
  #
25
20
  # @return [TTY::Table::Border]
@@ -27,18 +22,10 @@ module TTY
27
22
  # @api private
28
23
  attr_reader :border_class
29
24
 
30
- TABLE_DELEGATED_METHODS = [:column_widths, :alignments]
25
+ TABLE_DELEGATED_METHODS = [:column_widths, :column_aligns]
31
26
 
32
27
  delegatable_method :table, *TABLE_DELEGATED_METHODS
33
28
 
34
- # Return an AlignmentSet object for processing alignments
35
- #
36
- # @return [AlignmentSet]
37
- #
38
- # @api private
39
- attr_reader :alignment_set
40
- private :alignment_set
41
-
42
29
  # Initialize and setup a Renderer
43
30
  #
44
31
  # @param [Hash] options
@@ -88,16 +75,14 @@ module TTY
88
75
  def render(table, border_class=Border::Null)
89
76
  @table = table
90
77
  @border_class = table.border_class || border_class
78
+ return if table.empty?
91
79
 
92
- return if table.to_a.empty?
93
- # setup(options)
94
80
  body = []
95
81
  unless table.length.zero?
96
82
  ColumnSet.new(table).extract_widths!
97
83
  # TODO: throw an error if too many columns as compared to terminal width
98
84
  # and then change table.orientation from vertical to horizontal
99
85
  # TODO: Decide about table orientation
100
-
101
86
  body += render_header
102
87
  body += render_rows
103
88
  end
@@ -114,10 +99,10 @@ module TTY
114
99
  def render_header
115
100
  header = table.header
116
101
  if header && !header.empty?
117
- aligned = alignments.align_header header,
118
- :column_widths => column_widths
119
- border = border_class.new(aligned)
120
- [border.top_line, border.row_line].compact
102
+ operations = table.operations
103
+ operations.run_operations(:alignment, header)
104
+ border = border_class.new(header, table.border)
105
+ [ border.top_line, border.row_line ].compact
121
106
  else
122
107
  []
123
108
  end
@@ -129,17 +114,41 @@ module TTY
129
114
  #
130
115
  # @api private
131
116
  def render_rows
132
- aligned = alignments.align_rows table.to_a,
133
- :column_widths => column_widths
134
-
135
- first_row_border = border_class.new(aligned.first)
136
- aligned_border = aligned.map { |row| border_class.new(row).row_line }
117
+ operations = table.operations
118
+ table.each do |row|
119
+ operations.run_operations(:alignment, row)
120
+ end
121
+ aligned = table.to_a
122
+ first_row_border = border_class.new(aligned.first, table.border)
123
+ aligned_border = aligned.each_with_index.map { |row, index|
124
+ render_row(row, aligned.size != (index += 1))
125
+ }
137
126
 
138
127
  [ table.header ? first_row_border.separator : first_row_border.top_line,
139
128
  aligned_border,
140
129
  first_row_border.bottom_line ].compact
141
130
  end
142
131
 
132
+ # Format a single row with border
133
+ #
134
+ # @param [Array] row
135
+ # a row to decorate
136
+ #
137
+ # @param [Boolean] is_last_row
138
+ #
139
+ # @api private
140
+ def render_row(row, is_last_row)
141
+ border = border_class.new(row, table.border)
142
+ separator = border.separator
143
+ row_line = border.row_line
144
+
145
+ if (table.border.separator == TTY::Table::Border::EACH_ROW) && is_last_row
146
+ [row_line, separator]
147
+ else
148
+ row_line
149
+ end
150
+ end
151
+
143
152
  end # Basic
144
153
  end # Renderer
145
154
  end # Table
@@ -59,7 +59,7 @@ module TTY
59
59
  #
60
60
  # @api private
61
61
  def pick_renderer(type=nil)
62
- type ? RENDERER_MAPPER[type].new : self.renderer
62
+ self.renderer= (type ? RENDERER_MAPPER[type].new : self.renderer)
63
63
  end
64
64
 
65
65
  # Return the default renderer
@@ -82,8 +82,20 @@ module TTY
82
82
 
83
83
  # Add custom border for the renderer
84
84
  #
85
+ # @raise [TypeError]
86
+ # raised if the klass does not inherit from Table::Border
87
+ #
88
+ # @raise [NoImplemntationError]
89
+ # raise if the klass does not implement def_border
90
+ #
85
91
  # @api public
86
92
  def renders_with(klass)
93
+ unless klass <= TTY::Table::Border
94
+ raise TypeError, "#{klass} should inherit from TTY::Table::Border"
95
+ end
96
+ unless klass.characters
97
+ raise NoImplementationError, "#{klass} should implement def_border"
98
+ end
87
99
  @border_class = klass
88
100
  end
89
101
 
@@ -0,0 +1,174 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'tty/vector'
4
+
5
+ module TTY
6
+ class Table
7
+
8
+ # Convert an Array row into Row
9
+ #
10
+ # @return [TTY::Table::Row]
11
+ #
12
+ # @api private
13
+ def to_row(row, header=nil)
14
+ Row.new(row, header)
15
+ end
16
+
17
+ # A class that represents a row in a table.
18
+ class Row < Vector
19
+ include Equatable
20
+ extend Forwardable
21
+
22
+ def_delegators :to_ary, :join
23
+
24
+ # The row attributes
25
+ #
26
+ # @return [Array]
27
+ #
28
+ # @api private
29
+ attr_reader :attributes
30
+
31
+ # The row data
32
+ #
33
+ # @return [Hash]
34
+ #
35
+ # @api private
36
+ attr_reader :data
37
+
38
+ # Initialize a Row
39
+ #
40
+ # @example
41
+ # row = new TTY::Table::Row.new [1,2,3]
42
+ # row[1] # => 2
43
+ #
44
+ # row = new TTY::Table::Row.new [1,2,3], %w[a b c]
45
+ # row[0] # => 1
46
+ # row['a'] # => 1
47
+ #
48
+ # row = new TTY::Table::Row.new {"a": 1, "b": 2, "c": 3}
49
+ # row[0] # => 1
50
+ # row['a'] # => 1
51
+ #
52
+ # @param [#to_ary] data
53
+ # the row data
54
+ #
55
+ # @return [undefined]
56
+ #
57
+ # @api public
58
+ def initialize(data, header=nil)
59
+ case data
60
+ when Array
61
+ @attributes = (header || (0...data.length)).to_a
62
+ fields = data.inject([]) { |arr, datum| arr << to_field(datum) }
63
+ @data = Hash[@attributes.zip(fields)]
64
+ when Hash
65
+ @data = data.dup
66
+ fields = @data.values.inject([]){|arr, datum| arr << to_field(datum) }
67
+ @attributes = (header || data.keys).to_a
68
+ @data = Hash[@attributes.zip(fields)]
69
+ end
70
+ end
71
+
72
+ # Instantiates a new field
73
+ #
74
+ # @api public
75
+ def to_field(options=nil)
76
+ Field.new(options)
77
+ end
78
+
79
+ # Lookup a value in the row given an attribute allowing for Array or
80
+ # Hash like indexing
81
+ #
82
+ # @exmaple
83
+ # row[1]
84
+ # row[:id]
85
+ # row.call(:id)
86
+ #
87
+ # @api public
88
+ def [](attribute)
89
+ case attribute
90
+ when Integer
91
+ data[attributes[attribute]].value
92
+ else
93
+ data.fetch(attribute) do |name|
94
+ raise UnknownAttributeError, "the attribute #{name} is unkown"
95
+ end.value
96
+ end
97
+ end
98
+ alias :call :[]
99
+
100
+ # Set value at index
101
+ #
102
+ # @example
103
+ # row[attribute] = value
104
+ #
105
+ # @api public
106
+ def []=(attribute, value)
107
+ case attribute
108
+ when Integer
109
+ self.data[attributes[attribute]] = to_field(value)
110
+ else
111
+ self.data[attribute] = to_field(value)
112
+ self.attributes << attribute unless attributes.include?(attribute)
113
+ end
114
+ end
115
+
116
+ # Number of data items in a row
117
+ #
118
+ # @return [Integer]
119
+ #
120
+ # @api public
121
+ def size
122
+ data.size
123
+ end
124
+ alias :length :size
125
+
126
+ # Convert the Row into Array
127
+ #
128
+ # @example
129
+ # array = row.to_ary
130
+ #
131
+ # @return [Array]
132
+ #
133
+ # @api public
134
+ def to_ary
135
+ to_hash.values_at(*attributes)
136
+ end
137
+
138
+ # Convert the Row into hash
139
+ #
140
+ # @return [Hash]
141
+ #
142
+ # @api public
143
+ def to_hash
144
+ hash = data.dup
145
+ hash.update(hash) { |key, val| val.value if val }
146
+ end
147
+
148
+ # Check if this row is equivalent to another row
149
+ #
150
+ # @return [Boolean]
151
+ #
152
+ # @api public
153
+ def ==(other)
154
+ to_a == other.to_a
155
+ end
156
+ alias :eql? :==
157
+
158
+ # Provide a unique hash value. If a row contains the same data as another
159
+ # row, they will hash to the same value.
160
+ #
161
+ # @api public
162
+ def hash
163
+ to_a.hash
164
+ end
165
+
166
+ def map!(&block)
167
+ data.values_at(*attributes).each do |field|
168
+ field.value = block.call(field)
169
+ end
170
+ end
171
+ end # Row
172
+
173
+ end # Table
174
+ end # TTY
data/lib/tty/table.rb CHANGED
@@ -4,8 +4,14 @@ require 'forwardable'
4
4
  require 'tty/table/renderer'
5
5
  require 'tty/table/error'
6
6
  require 'tty/table/validatable'
7
+ require 'tty/table/header'
8
+ require 'tty/table/row'
7
9
 
8
10
  module TTY
11
+ # A core class intended for storing data in a structured, tabular form.
12
+ # Once the data is stored in a TTY::Table various operations can be performed
13
+ # before the information is dumped into a stdout.
14
+ #
9
15
  class Table
10
16
  include Comparable, Enumerable, Renderer, Conversion
11
17
  include Validatable, Equatable
@@ -35,10 +41,10 @@ module TTY
35
41
 
36
42
  # The table column alignments
37
43
  #
38
- # @return [Operation::AlignmentSet]
44
+ # @return [Array]
39
45
  #
40
46
  # @api private
41
- attr_reader :alignments
47
+ attr_reader :column_aligns
42
48
 
43
49
  # The table border class
44
50
  #
@@ -47,11 +53,21 @@ module TTY
47
53
 
48
54
  # The table orientation out of :horizontal and :vertical
49
55
  #
50
- # @reutnr [TTY::Table::Orientation]
56
+ # @reutrn [TTY::Table::Orientation]
51
57
  #
52
58
  # @api public
53
59
  attr_reader :orientation
54
60
 
61
+ # A callable object used for formatting field content
62
+ #
63
+ # @api public
64
+ attr_accessor :filter
65
+
66
+ # The table operations applied to rows
67
+ #
68
+ # @api public
69
+ attr_reader :operations
70
+
55
71
  # Subset of safe methods that both Array and Hash implement
56
72
  def_delegators(:@rows, :[], :assoc, :flatten, :include?, :index,
57
73
  :length, :select, :to_a, :values_at, :pretty_print, :rassoc)
@@ -124,26 +140,41 @@ module TTY
124
140
  # used to format table individual column alignment
125
141
  # @option options [String] :column_widths
126
142
  # used to format table individula column width
143
+ # @option options [Symbol] :orientation
144
+ # used to transform table orientation
127
145
  #
128
146
  # @return [TTY::Table]
129
147
  #
130
148
  # @api private
131
149
  def initialize(options={}, &block)
132
150
  validate_options! options
133
-
134
- @header = options.fetch(:header) { nil }
135
- @rows = coerce options.fetch(:rows) { [] }
151
+ @header = (value = options[:header]) ? Header.new(value) : nil
152
+ @rows = coerce(options.fetch(:rows) { Row.new([]) })
136
153
  @renderer = pick_renderer options[:renderer]
137
- @orientation = Orientation.coerce options.fetch(:orientation) { :horizontal }
154
+ @border = TTY::Table::BorderOptions.from(options.delete(:border))
155
+ @orientation = Orientation.coerce(options.fetch(:orientation) { :horizontal })
138
156
  # TODO: assert that row_size is the same as column widths & aligns
139
157
  @column_widths = Array(options.delete(:column_widths)).map(&:to_i)
140
- @alignments = Operation::AlignmentSet.new Array(options.delete(:column_aligns)).map(&:to_sym)
158
+ @column_aligns = Array(options.delete(:column_aligns)).map(&:to_sym)
159
+ @operations = TTY::Table::Operations.new(self)
160
+ @operations.add_operation(:alignment, Operation::AlignmentSet.new(@column_aligns))
161
+ @filter = options.fetch(:filter) { nil }
162
+ @width = options.fetch(:width) { TTY.terminal.width }
141
163
 
142
164
  assert_row_sizes @rows
143
165
  @orientation.transform(self)
144
166
  yield_or_eval &block if block_given?
145
167
  end
146
168
 
169
+ # Set table fields filter
170
+ #
171
+ # @param [#call] block
172
+ #
173
+ # @api public
174
+ def filter(&block)
175
+ @operations.add_operation(:filter, block)
176
+ end
177
+
147
178
  # Sets table orientation
148
179
  #
149
180
  # @param [String,Symbol] value
@@ -155,6 +186,8 @@ module TTY
155
186
 
156
187
  # Marks this table as rotated
157
188
  #
189
+ # @return [Boolean]
190
+ #
158
191
  # @api public
159
192
  def rotated?
160
193
  @rotated
@@ -174,7 +207,7 @@ module TTY
174
207
  #
175
208
  # @api private
176
209
  def rotate_vertical
177
- @rows = ([header].compact + rows).transpose
210
+ @rows = ([header].compact + rows).transpose.map { |row| to_row(row) }
178
211
  @header = [] if header
179
212
  @rotated = true
180
213
  end
@@ -185,13 +218,31 @@ module TTY
185
218
  def rotate_horizontal
186
219
  transposed = rows.transpose
187
220
  if header && header.empty?
188
- @rows = transposed[1..-1]
189
221
  @header = transposed[0]
222
+ @rows = transposed[1..-1].map { |row| to_row(row, @header) }
190
223
  elsif rotated?
191
- @rows = transposed
224
+ @rows = transposed.map { |row| to_row(row) }
192
225
  end
193
226
  end
194
227
 
228
+ # Store border characters, style and separator for the table rendering
229
+ #
230
+ # @param [Hash, BorderOptions] options
231
+ #
232
+ # @yield [] block representing border options
233
+ #
234
+ # @api public
235
+ def border(options=(not_set=true), &block)
236
+ @border = TTY::Table::BorderOptions.new unless @border
237
+ if block_given?
238
+ border_dsl = TTY::Table::BorderDSL.new(&block)
239
+ @border = border_dsl.options
240
+ elsif !not_set
241
+ @border = TTY::Table::BorderOptions.from(options)
242
+ end
243
+ @border
244
+ end
245
+
195
246
  # Lookup element of the table given a row(i) and column(j)
196
247
  #
197
248
  # @api public
@@ -241,14 +292,19 @@ module TTY
241
292
  end
242
293
 
243
294
  # Return a column number at the index of the table as an Array.
295
+ # If the table has a header then column can be searched by header name.
244
296
  # When a block is given, the elements of that Array are iterated over.
245
297
  #
246
298
  # @example
299
+ # header = [:h1, :h2]
247
300
  # rows = [ ['a1', 'a2'], ['b1', 'b2'] ]
248
- # table = TTY::Table.new :rows => rows
249
- # table.column(1) { |element| ... }
301
+ # table = TTY::Table.new :rows => rows, :header => header
302
+ # table.column(1)
303
+ # table.column(1) { |element| ... }
304
+ # table.column(:h1)
305
+ # table.column(:h1) { |element| ... }
250
306
  #
251
- # @param [Integer] index
307
+ # @param [Integer, String, Symbol] index
252
308
  #
253
309
  # @yield []
254
310
  # optional block to execute in the iteration operation
@@ -257,11 +313,12 @@ module TTY
257
313
  #
258
314
  # @api public
259
315
  def column(index)
316
+ index_unknown = index.is_a?(Integer) && (index >= column_size || index < 0)
260
317
  if block_given?
261
- return self if index >= column_size || index < 0
262
- rows.map { |row| yield row[index].compact }
318
+ return self if index_unknown
319
+ rows.map { |row| yield row[index] }
263
320
  else
264
- return nil if index >= column_size || index < 0
321
+ return nil if index_unknown
265
322
  rows.map { |row| row[index] }.compact
266
323
  end
267
324
  end
@@ -276,7 +333,7 @@ module TTY
276
333
  def <<(row)
277
334
  rows_copy = rows.dup
278
335
  assert_row_sizes rows_copy << row
279
- rows << row
336
+ rows << to_row(row)
280
337
  self
281
338
  end
282
339
 
@@ -293,8 +350,25 @@ module TTY
293
350
  # @api public
294
351
  def each
295
352
  return to_enum unless block_given?
296
- rows.each do |row|
297
- yield row
353
+ rows.each { |row| yield row }
354
+ self
355
+ end
356
+
357
+ # Iterate over each element yielding in addition row and column index
358
+ #
359
+ # @example
360
+ # table = TTY::Table.new(header, tuples)
361
+ # table.each_with_index { |el, row, col| puts "#{el} at #{row},#{col}" }
362
+ #
363
+ # @return self
364
+ #
365
+ # @api public
366
+ def each_with_index
367
+ return to_enum unless block_given?
368
+ rows.each_with_index do |row, row_index|
369
+ row.each_with_index do |el, col_index|
370
+ yield el, row_index, col_index
371
+ end
298
372
  end
299
373
  self
300
374
  end
@@ -375,7 +449,8 @@ module TTY
375
449
  #
376
450
  # @api public
377
451
  def coerce(rows)
378
- convert_to_array(rows)
452
+ rows = convert_to_array(rows)
453
+ rows.map { |row| to_row(row, header) }
379
454
  end
380
455
 
381
456
  private
@@ -57,7 +57,7 @@ module TTY
57
57
 
58
58
  as_unicode do
59
59
  chars = text.chars.to_a
60
- return chars.join if chars.length < length
60
+ return chars.join if chars.length <= length
61
61
  stop = chars[0, length_without_trailing].rindex(separator)
62
62
 
63
63
  chars[0, stop || length_without_trailing].join + trailing
data/lib/tty/vector.rb CHANGED
@@ -41,7 +41,7 @@ module TTY
41
41
  #
42
42
  # @api public
43
43
  def [](indx)
44
- elements[i]
44
+ elements[indx]
45
45
  end
46
46
  alias at []
47
47
  alias element []
@@ -58,7 +58,7 @@ module TTY
58
58
  #
59
59
  # @api public
60
60
  def []=(indx, value)
61
- elements[index] = value
61
+ self.elements[indx] = value
62
62
  end
63
63
  alias set_element []=
64
64
 
@@ -71,9 +71,9 @@ module TTY
71
71
  # @return [self]
72
72
  #
73
73
  # @api public
74
- def each(&block)
75
- return to_enum(:each) unless block_given?
76
- to_ary.each(&block)
74
+ def each
75
+ return to_enum unless block_given?
76
+ to_ary.each { |element| yield element }
77
77
  self
78
78
  end
79
79
 
@@ -83,7 +83,7 @@ module TTY
83
83
  #
84
84
  # @api public
85
85
  def to_ary
86
- elements
86
+ @elements
87
87
  end
88
88
 
89
89
  # Check if there are not elements.
@@ -103,6 +103,7 @@ module TTY
103
103
  def size
104
104
  to_ary.size
105
105
  end
106
+ alias :length :size
106
107
 
107
108
  # Return the vector elements in an array.
108
109
  #
@@ -110,7 +111,7 @@ module TTY
110
111
  #
111
112
  # @api public
112
113
  def to_a
113
- elements.dup
114
+ to_ary.dup
114
115
  end
115
116
 
116
117
  end # Vector
data/lib/tty/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  module TTY
4
- VERSION = "0.0.7"
4
+ VERSION = "0.0.8"
5
5
  end