From 2519818cc9a1b274f6f6ad686258ac2969b0f5c4 Mon Sep 17 00:00:00 2001 From: Kyrylo Silin Date: Fri, 19 Oct 2018 22:03:41 +0800 Subject: Rename HistoryArray to Ring `HistoryArray` is a very specific name and it doesn't tell the reader what it *really* means unless you read its code or the docs of the class. On the other hand, `Ring` is a [very well-known term][1], which means exactly what `HistoryArray` does. The alias name for it is circular buffer. I chose `Ring` because it is shorter and used by Golang, so I expect programmers to be familiar with `Ring`. [1]: https://en.wikipedia.org/wiki/Circular_buffer --- lib/pry.rb | 2 +- lib/pry/history_array.rb | 117 --------------------------------------------- lib/pry/pry_instance.rb | 8 ++-- lib/pry/ring.rb | 117 +++++++++++++++++++++++++++++++++++++++++++++ spec/history_array_spec.rb | 71 --------------------------- spec/pry_spec.rb | 4 +- spec/ring_spec.rb | 71 +++++++++++++++++++++++++++ 7 files changed, 195 insertions(+), 195 deletions(-) delete mode 100644 lib/pry/history_array.rb create mode 100644 lib/pry/ring.rb delete mode 100644 spec/history_array_spec.rb create mode 100644 spec/ring_spec.rb diff --git a/lib/pry.rb b/lib/pry.rb index ccf0af6c..1faad7be 100644 --- a/lib/pry.rb +++ b/lib/pry.rb @@ -144,7 +144,7 @@ require 'pathname' require 'pry/version' require 'pry/repl' require 'pry/code' -require 'pry/history_array' +require 'pry/ring' require 'pry/helpers' require 'pry/code_object' require 'pry/method' diff --git a/lib/pry/history_array.rb b/lib/pry/history_array.rb deleted file mode 100644 index ad476011..00000000 --- a/lib/pry/history_array.rb +++ /dev/null @@ -1,117 +0,0 @@ -class Pry - # A history array is an array to which you can only add elements. Older - # entries are removed progressively, so that the array never contains more than - # N elements. - # - # History arrays are used by Pry to store the output of the last commands. - # - # @example - # ary = Pry::HistoryArray.new 10 - # ary << 1 << 2 << 3 - # ary[0] # => 1 - # ary[1] # => 2 - # 10.times { |n| ary << n } - # ary[0] # => nil - # ary[-1] # => 9 - class HistoryArray - include Enumerable - - # @param [Integer] size Maximum amount of objects in the array - def initialize(size) - @max_size = size - - @hash = {} - @count = 0 - end - - # Pushes an object at the end of the array - # @param [Object] value Object to be added - def <<(value) - @hash[@count] = value - - if @hash.size > max_size - @hash.delete(@count - max_size) - end - - @count += 1 - - self - end - - # @overload [](index) - # @param [Integer] index Index of the item to access. - # @return [Object, nil] Item at that index or nil if it has been removed. - # @overload [](index, size) - # @param [Integer] index Index of the first item to access. - # @param [Integer] size Amount of items to access - # @return [Array, nil] The selected items. Nil if index is greater than - # the size of the array. - # @overload [](range) - # @param [Range] range Range of indices to access. - # @return [Array, nil] The selected items. Nil if index is greater than - # the size of the array. - def [](index_or_range, size = nil) - unless index_or_range.is_a?(Integer) - range = convert_range(index_or_range) - return range.begin > @count ? nil : range.map { |n| @hash[n] } - end - - index = convert_index(index_or_range) - return @hash[index] unless size - return if index > @count - - end_index = index + size - (index...[end_index, @count].min).map { |n| @hash[n] } - end - - # @return [Integer] Amount of objects in the array - def size - @count - end - alias count size - alias length size - - def empty? - size == 0 - end - - def each - ((@count - size)...@count).each do |n| - yield @hash[n] - end - end - - def to_a - ((@count - size)...@count).map { |n| @hash[n] } - end - - # @return [Hash] copy of the internal @hash history - def to_h - @hash.dup - end - - def pop! - @hash.delete @count - 1 - @count -= 1 - end - - def inspect - "#<#{self.class} size=#{size} first=#{@count - size} max_size=#{max_size}>" - end - - # @return [Integer] Maximum amount of objects in the array - attr_reader :max_size - - private - def convert_index(n) - n >= 0 ? n : @count + n - end - - def convert_range(range) - end_index = convert_index(range.end) - end_index += 1 unless range.exclude_end? - - Range.new(convert_index(range.begin), [end_index, @count].min, true) - end - end -end diff --git a/lib/pry/pry_instance.rb b/lib/pry/pry_instance.rb index 16b4ec99..32901f7c 100644 --- a/lib/pry/pry_instance.rb +++ b/lib/pry/pry_instance.rb @@ -72,8 +72,8 @@ class Pry @config = Pry::Config.new config.merge!(options) push_prompt(config.prompt) - @input_array = Pry::HistoryArray.new config.memory_size - @output_array = Pry::HistoryArray.new config.memory_size + @input_array = Pry::Ring.new(config.memory_size) + @output_array = Pry::Ring.new(config.memory_size) @custom_completions = config.command_completions set_last_result nil @input_array << nil @@ -177,8 +177,8 @@ class Pry undef :memory_size= if method_defined? :memory_size= def memory_size=(size) - @input_array = Pry::HistoryArray.new(size) - @output_array = Pry::HistoryArray.new(size) + @input_array = Pry::Ring.new(size) + @output_array = Pry::Ring.new(size) end # Inject all the sticky locals into the current binding. diff --git a/lib/pry/ring.rb b/lib/pry/ring.rb new file mode 100644 index 00000000..4980cb3c --- /dev/null +++ b/lib/pry/ring.rb @@ -0,0 +1,117 @@ +class Pry + # A ring is an array to which you can only add elements. Older entries are + # removed progressively, so that the array never contains more than N + # elements. + # + # Rings are used by Pry to store the output of the last commands. + # + # @example + # ring = Pry::Ring.new(10) + # ring << 1 << 2 << 3 + # ring[0] # => 1 + # ring[1] # => 2 + # 10.times { |n| ring << n } + # ring[0] # => nil + # ring[-1] # => 9 + class Ring + include Enumerable + + # @param [Integer] size Maximum amount of objects in the array + def initialize(size) + @max_size = size + + @hash = {} + @count = 0 + end + + # Pushes an object at the end of the array + # @param [Object] value Object to be added + def <<(value) + @hash[@count] = value + + if @hash.size > max_size + @hash.delete(@count - max_size) + end + + @count += 1 + + self + end + + # @overload [](index) + # @param [Integer] index Index of the item to access. + # @return [Object, nil] Item at that index or nil if it has been removed. + # @overload [](index, size) + # @param [Integer] index Index of the first item to access. + # @param [Integer] size Amount of items to access + # @return [Array, nil] The selected items. Nil if index is greater than + # the size of the array. + # @overload [](range) + # @param [Range] range Range of indices to access. + # @return [Array, nil] The selected items. Nil if index is greater than + # the size of the array. + def [](index_or_range, size = nil) + unless index_or_range.is_a?(Integer) + range = convert_range(index_or_range) + return range.begin > @count ? nil : range.map { |n| @hash[n] } + end + + index = convert_index(index_or_range) + return @hash[index] unless size + return if index > @count + + end_index = index + size + (index...[end_index, @count].min).map { |n| @hash[n] } + end + + # @return [Integer] Amount of objects in the array + def size + @count + end + alias count size + alias length size + + def empty? + size == 0 + end + + def each + ((@count - size)...@count).each do |n| + yield @hash[n] + end + end + + def to_a + ((@count - size)...@count).map { |n| @hash[n] } + end + + # @return [Hash] copy of the internal @hash history + def to_h + @hash.dup + end + + def pop! + @hash.delete @count - 1 + @count -= 1 + end + + def inspect + "#<#{self.class} size=#{size} first=#{@count - size} max_size=#{max_size}>" + end + + # @return [Integer] Maximum amount of objects in the array + attr_reader :max_size + + private + def convert_index(n) + n >= 0 ? n : @count + n + end + + def convert_range(range) + end_index = convert_index(range.end) + end_index += 1 unless range.exclude_end? + + Range.new(convert_index(range.begin), [end_index, @count].min, true) + end + end +end diff --git a/spec/history_array_spec.rb b/spec/history_array_spec.rb deleted file mode 100644 index 2d7d7b8b..00000000 --- a/spec/history_array_spec.rb +++ /dev/null @@ -1,71 +0,0 @@ -require_relative 'helper' - -describe Pry::HistoryArray do - before do - @array = Pry::HistoryArray.new 10 - @populated = @array.dup << 1 << 2 << 3 << 4 - end - - it 'should have a maximum size specifed at creation time' do - expect(@array.max_size).to eq 10 - end - - it 'should be able to be added objects to' do - expect(@populated.size).to eq 4 - expect(@populated.to_a).to eq [1, 2, 3, 4] - end - - it 'should be able to access single elements' do - expect(@populated[2]).to eq 3 - end - - it 'should be able to access negative indices' do - expect(@populated[-1]).to eq 4 - end - - it 'should be able to access ranges' do - expect(@populated[1..2]).to eq [2, 3] - end - - it 'should be able to access ranges starting from a negative index' do - expect(@populated[-2..3]).to eq [3, 4] - end - - it 'should be able to access ranges ending at a negative index' do - expect(@populated[2..-1]).to eq [3, 4] - end - - it 'should be able to access ranges using only negative indices' do - expect(@populated[-2..-1]).to eq [3, 4] - end - - it 'should be able to use range where end is excluded' do - expect(@populated[-2...-1]).to eq [3] - end - - it 'should be able to access slices using a size' do - expect(@populated[-3, 2]).to eq [2, 3] - end - - it 'should remove older entries' do - 11.times { |n| @array << n } - - expect(@array[0]).to eq nil - expect(@array[1]).to eq 1 - expect(@array[10]).to eq 10 - end - - it 'should not be larger than specified maximum size' do - 12.times { |n| @array << n } - expect(@array.entries.compact.size).to eq 10 - end - - it 'should pop!' do - @populated.pop! - expect(@populated.to_a).to eq [1, 2, 3] - end - - it 'should return an indexed hash' do - expect(@populated.to_h[0]).to eq @populated[0] - end -end diff --git a/spec/pry_spec.rb b/spec/pry_spec.rb index a727ae52..3be96b06 100644 --- a/spec/pry_spec.rb +++ b/spec/pry_spec.rb @@ -273,7 +273,7 @@ describe Pry do t.eval "42" res = t.eval "_out_" - expect(res).to be_a_kind_of Pry::HistoryArray + expect(res).to be_a_kind_of(Pry::Ring) expect(res[1..2]).to eq [:foo, 42] end @@ -283,7 +283,7 @@ describe Pry do t.eval "42" res = t.eval "_in_" - expect(res).to be_a_kind_of Pry::HistoryArray + expect(res).to be_a_kind_of(Pry::Ring) expect(res[1..2]).to eq [":foo\n", "42\n"] end diff --git a/spec/ring_spec.rb b/spec/ring_spec.rb new file mode 100644 index 00000000..65630d12 --- /dev/null +++ b/spec/ring_spec.rb @@ -0,0 +1,71 @@ +require_relative 'helper' + +describe Pry::Ring do + before do + @ring = Pry::Ring.new(10) + @populated = @ring.dup << 1 << 2 << 3 << 4 + end + + it 'should have a maximum size specifed at creation time' do + expect(@ring.max_size).to eq 10 + end + + it 'should be able to be added objects to' do + expect(@populated.size).to eq 4 + expect(@populated.to_a).to eq [1, 2, 3, 4] + end + + it 'should be able to access single elements' do + expect(@populated[2]).to eq 3 + end + + it 'should be able to access negative indices' do + expect(@populated[-1]).to eq 4 + end + + it 'should be able to access ranges' do + expect(@populated[1..2]).to eq [2, 3] + end + + it 'should be able to access ranges starting from a negative index' do + expect(@populated[-2..3]).to eq [3, 4] + end + + it 'should be able to access ranges ending at a negative index' do + expect(@populated[2..-1]).to eq [3, 4] + end + + it 'should be able to access ranges using only negative indices' do + expect(@populated[-2..-1]).to eq [3, 4] + end + + it 'should be able to use range where end is excluded' do + expect(@populated[-2...-1]).to eq [3] + end + + it 'should be able to access slices using a size' do + expect(@populated[-3, 2]).to eq [2, 3] + end + + it 'should remove older entries' do + 11.times { |n| @ring << n } + + expect(@ring[0]).to eq nil + expect(@ring[1]).to eq 1 + expect(@ring[10]).to eq 10 + end + + it 'should not be larger than specified maximum size' do + 12.times { |n| @ring << n } + expect(@ring.entries.compact.size).to eq 10 + end + + it 'should pop!' do + @populated.pop! + expect(@populated.to_a).to eq [1, 2, 3] + end + + it 'should return an indexed hash' do + expect(@populated.to_h[0]).to eq @populated[0] + end +end -- cgit v1.2.1