pry 0.10.0.pre4-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +702 -0
  3. data/LICENSE +25 -0
  4. data/README.md +406 -0
  5. data/bin/pry +16 -0
  6. data/lib/pry.rb +161 -0
  7. data/lib/pry/cli.rb +220 -0
  8. data/lib/pry/code.rb +341 -0
  9. data/lib/pry/code/code_file.rb +103 -0
  10. data/lib/pry/code/code_range.rb +71 -0
  11. data/lib/pry/code/loc.rb +92 -0
  12. data/lib/pry/code_object.rb +172 -0
  13. data/lib/pry/color_printer.rb +55 -0
  14. data/lib/pry/command.rb +692 -0
  15. data/lib/pry/command_set.rb +443 -0
  16. data/lib/pry/commands.rb +6 -0
  17. data/lib/pry/commands/amend_line.rb +99 -0
  18. data/lib/pry/commands/bang.rb +20 -0
  19. data/lib/pry/commands/bang_pry.rb +17 -0
  20. data/lib/pry/commands/cat.rb +62 -0
  21. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  22. data/lib/pry/commands/cat/exception_formatter.rb +77 -0
  23. data/lib/pry/commands/cat/file_formatter.rb +67 -0
  24. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  25. data/lib/pry/commands/cd.rb +41 -0
  26. data/lib/pry/commands/change_inspector.rb +27 -0
  27. data/lib/pry/commands/change_prompt.rb +26 -0
  28. data/lib/pry/commands/code_collector.rb +165 -0
  29. data/lib/pry/commands/disable_pry.rb +27 -0
  30. data/lib/pry/commands/disabled_commands.rb +2 -0
  31. data/lib/pry/commands/easter_eggs.rb +112 -0
  32. data/lib/pry/commands/edit.rb +195 -0
  33. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  34. data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
  35. data/lib/pry/commands/exit.rb +42 -0
  36. data/lib/pry/commands/exit_all.rb +29 -0
  37. data/lib/pry/commands/exit_program.rb +23 -0
  38. data/lib/pry/commands/find_method.rb +193 -0
  39. data/lib/pry/commands/fix_indent.rb +19 -0
  40. data/lib/pry/commands/gem_cd.rb +26 -0
  41. data/lib/pry/commands/gem_install.rb +32 -0
  42. data/lib/pry/commands/gem_list.rb +33 -0
  43. data/lib/pry/commands/gem_open.rb +29 -0
  44. data/lib/pry/commands/gist.rb +101 -0
  45. data/lib/pry/commands/help.rb +164 -0
  46. data/lib/pry/commands/hist.rb +180 -0
  47. data/lib/pry/commands/import_set.rb +22 -0
  48. data/lib/pry/commands/install_command.rb +53 -0
  49. data/lib/pry/commands/jump_to.rb +29 -0
  50. data/lib/pry/commands/list_inspectors.rb +35 -0
  51. data/lib/pry/commands/list_prompts.rb +35 -0
  52. data/lib/pry/commands/ls.rb +114 -0
  53. data/lib/pry/commands/ls/constants.rb +47 -0
  54. data/lib/pry/commands/ls/formatter.rb +49 -0
  55. data/lib/pry/commands/ls/globals.rb +48 -0
  56. data/lib/pry/commands/ls/grep.rb +21 -0
  57. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  58. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  59. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  60. data/lib/pry/commands/ls/local_names.rb +35 -0
  61. data/lib/pry/commands/ls/local_vars.rb +39 -0
  62. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  63. data/lib/pry/commands/ls/methods.rb +57 -0
  64. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  65. data/lib/pry/commands/ls/self_methods.rb +32 -0
  66. data/lib/pry/commands/nesting.rb +25 -0
  67. data/lib/pry/commands/play.rb +103 -0
  68. data/lib/pry/commands/pry_backtrace.rb +25 -0
  69. data/lib/pry/commands/pry_version.rb +17 -0
  70. data/lib/pry/commands/raise_up.rb +32 -0
  71. data/lib/pry/commands/reload_code.rb +62 -0
  72. data/lib/pry/commands/reset.rb +18 -0
  73. data/lib/pry/commands/ri.rb +60 -0
  74. data/lib/pry/commands/save_file.rb +61 -0
  75. data/lib/pry/commands/shell_command.rb +48 -0
  76. data/lib/pry/commands/shell_mode.rb +25 -0
  77. data/lib/pry/commands/show_doc.rb +83 -0
  78. data/lib/pry/commands/show_info.rb +195 -0
  79. data/lib/pry/commands/show_input.rb +17 -0
  80. data/lib/pry/commands/show_source.rb +50 -0
  81. data/lib/pry/commands/simple_prompt.rb +22 -0
  82. data/lib/pry/commands/stat.rb +40 -0
  83. data/lib/pry/commands/switch_to.rb +23 -0
  84. data/lib/pry/commands/toggle_color.rb +24 -0
  85. data/lib/pry/commands/watch_expression.rb +105 -0
  86. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  87. data/lib/pry/commands/whereami.rb +190 -0
  88. data/lib/pry/commands/wtf.rb +57 -0
  89. data/lib/pry/config.rb +24 -0
  90. data/lib/pry/config/behavior.rb +139 -0
  91. data/lib/pry/config/convenience.rb +26 -0
  92. data/lib/pry/config/default.rb +165 -0
  93. data/lib/pry/core_extensions.rb +131 -0
  94. data/lib/pry/editor.rb +133 -0
  95. data/lib/pry/exceptions.rb +77 -0
  96. data/lib/pry/helpers.rb +5 -0
  97. data/lib/pry/helpers/base_helpers.rb +113 -0
  98. data/lib/pry/helpers/command_helpers.rb +156 -0
  99. data/lib/pry/helpers/documentation_helpers.rb +75 -0
  100. data/lib/pry/helpers/options_helpers.rb +27 -0
  101. data/lib/pry/helpers/table.rb +109 -0
  102. data/lib/pry/helpers/text.rb +107 -0
  103. data/lib/pry/history.rb +125 -0
  104. data/lib/pry/history_array.rb +121 -0
  105. data/lib/pry/hooks.rb +230 -0
  106. data/lib/pry/indent.rb +406 -0
  107. data/lib/pry/input_completer.rb +242 -0
  108. data/lib/pry/input_lock.rb +132 -0
  109. data/lib/pry/inspector.rb +27 -0
  110. data/lib/pry/last_exception.rb +61 -0
  111. data/lib/pry/method.rb +546 -0
  112. data/lib/pry/method/disowned.rb +53 -0
  113. data/lib/pry/method/patcher.rb +125 -0
  114. data/lib/pry/method/weird_method_locator.rb +186 -0
  115. data/lib/pry/module_candidate.rb +136 -0
  116. data/lib/pry/object_path.rb +82 -0
  117. data/lib/pry/output.rb +50 -0
  118. data/lib/pry/pager.rb +234 -0
  119. data/lib/pry/plugins.rb +103 -0
  120. data/lib/pry/prompt.rb +26 -0
  121. data/lib/pry/pry_class.rb +375 -0
  122. data/lib/pry/pry_instance.rb +654 -0
  123. data/lib/pry/rbx_path.rb +22 -0
  124. data/lib/pry/repl.rb +202 -0
  125. data/lib/pry/repl_file_loader.rb +74 -0
  126. data/lib/pry/rubygem.rb +82 -0
  127. data/lib/pry/terminal.rb +79 -0
  128. data/lib/pry/test/helper.rb +170 -0
  129. data/lib/pry/version.rb +3 -0
  130. data/lib/pry/wrapped_module.rb +373 -0
  131. metadata +248 -0
@@ -0,0 +1,75 @@
1
+ class Pry
2
+ module Helpers
3
+
4
+ # This class contains methods useful for extracting
5
+ # documentation from methods and classes.
6
+ module DocumentationHelpers
7
+
8
+ module_function
9
+
10
+ def process_rdoc(comment)
11
+ comment = comment.dup
12
+ comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { CodeRay.scan($1, :ruby).term }.
13
+ gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { "\e[1m#{$1}\e[0m" }.
14
+ gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { "\e[1m#{$1}\e[0m" }.
15
+ gsub(/\B\+(\w+?)\+\B/) { "\e[32m#{$1}\e[0m" }.
16
+ gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { CodeRay.scan($1, :ruby).term }.
17
+ gsub(/`(?:\s*\n)?([^\e]*?)\s*`/) { "`#{CodeRay.scan($1, :ruby).term}`" }
18
+ end
19
+
20
+ def process_yardoc_tag(comment, tag)
21
+ in_tag_block = nil
22
+ comment.lines.map do |v|
23
+ if in_tag_block && v !~ /^\S/
24
+ Pry::Helpers::Text.strip_color Pry::Helpers::Text.strip_color(v)
25
+ elsif in_tag_block
26
+ in_tag_block = false
27
+ v
28
+ else
29
+ in_tag_block = true if v =~ /^@#{tag}/
30
+ v
31
+ end
32
+ end.join
33
+ end
34
+
35
+ def process_yardoc(comment)
36
+ yard_tags = ["param", "return", "option", "yield", "attr", "attr_reader", "attr_writer",
37
+ "deprecate", "example", "raise"]
38
+ (yard_tags - ["example"]).inject(comment) { |a, v| process_yardoc_tag(a, v) }.
39
+ gsub(/^@(#{yard_tags.join("|")})/) { "\e[33m#{$1}\e[0m" }
40
+ end
41
+
42
+ def process_comment_markup(comment)
43
+ process_yardoc process_rdoc(comment)
44
+ end
45
+
46
+ # @param [String] code
47
+ # @return [String]
48
+ def strip_comments_from_c_code(code)
49
+ code.sub(/\A\s*\/\*.*?\*\/\s*/m, '')
50
+ end
51
+
52
+ # Given a string that makes up a comment in a source-code file parse out the content
53
+ # that the user is intended to read. (i.e. without leading indentation, #-characters
54
+ # or shebangs)
55
+ #
56
+ # @param [String] comment
57
+ # @return [String]
58
+ def get_comment_content(comment)
59
+ comment = comment.dup
60
+ # Remove #!/usr/bin/ruby
61
+ comment.gsub!(/\A\#!.*$/, '')
62
+ # Remove leading empty comment lines
63
+ comment.gsub!(/\A\#+?$/, '')
64
+ comment.gsub!(/^\s*#/, '')
65
+ strip_leading_whitespace(comment)
66
+ end
67
+
68
+ # @param [String] text
69
+ # @return [String]
70
+ def strip_leading_whitespace(text)
71
+ Pry::Helpers::CommandHelpers.unindent(text)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,27 @@
1
+ class Pry
2
+ module Helpers
3
+ module OptionsHelpers
4
+ module_function
5
+
6
+ # Add method options to the Slop instance
7
+ def method_options(opt)
8
+ @method_target = target
9
+ opt.on :M, "instance-methods", "Operate on instance methods."
10
+ opt.on :m, :methods, "Operate on methods."
11
+ opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors.", :as => :count
12
+ opt.on :c, :context, "Select object context to run under.", :argument => true do |context|
13
+ @method_target = Pry.binding_for(target.eval(context))
14
+ end
15
+ end
16
+
17
+ # Get the method object parsed by the slop instance
18
+ def method_object
19
+ @method_object ||= get_method_or_raise(args.empty? ? nil : args.join(" "), @method_target,
20
+ :super => opts[:super],
21
+ :instance => opts.present?(:'instance-methods') && !opts.present?(:'methods'),
22
+ :methods => opts.present?(:'methods') && !opts.present?(:'instance-methods')
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,109 @@
1
+ class Pry
2
+ module Helpers
3
+ def self.tablify_or_one_line(heading, things)
4
+ plain_heading = Pry::Helpers::Text.strip_color(heading)
5
+ attempt = Table.new(things, :column_count => things.size)
6
+ if attempt.fits_on_line?(Terminal.width! - plain_heading.size - 2)
7
+ "#{heading}: #{attempt}\n"
8
+ else
9
+ "#{heading}: \n#{tablify_to_screen_width(things, :indent => ' ')}\n"
10
+ end
11
+ end
12
+
13
+ def self.tablify_to_screen_width(things, options = {})
14
+ things = things.compact
15
+ if indent = options[:indent]
16
+ usable_width = Terminal.width! - indent.size
17
+ tablify(things, usable_width).to_s.gsub(/^/, indent)
18
+ else
19
+ tablify(things, Terminal.width!).to_s
20
+ end
21
+ end
22
+
23
+ def self.tablify(things, line_length)
24
+ table = Table.new(things, :column_count => things.size)
25
+ table.column_count -= 1 until 1 == table.column_count or
26
+ table.fits_on_line?(line_length)
27
+ table
28
+ end
29
+
30
+ class Table
31
+ attr_reader :items, :column_count
32
+ def initialize items, args = {}
33
+ @column_count = args[:column_count]
34
+ self.items = items
35
+ end
36
+
37
+ def to_s
38
+ rows_to_s.join("\n")
39
+ end
40
+
41
+ def rows_to_s style = :color_on
42
+ widths = columns.map{|e| _max_width(e)}
43
+ @rows_without_colors.map do |r|
44
+ padded = []
45
+ r.each_with_index do |e,i|
46
+ next unless e
47
+ item = e.ljust(widths[i])
48
+ item.sub! e, _recall_color_for(e) if :color_on == style
49
+ padded << item
50
+ end
51
+ padded.join(Pry.config.ls.separator)
52
+ end
53
+ end
54
+
55
+ def items= items
56
+ @items = items
57
+ _rebuild_colorless_cache
58
+ _recolumn
59
+ items
60
+ end
61
+
62
+ def column_count= n
63
+ @column_count = n
64
+ _recolumn
65
+ end
66
+
67
+ def fits_on_line? line_length
68
+ _max_width(rows_to_s :no_color) <= line_length
69
+ end
70
+
71
+ def columns
72
+ @rows_without_colors.transpose
73
+ end
74
+
75
+ def ==(other); items == other.to_a end
76
+ def to_a; items.to_a end
77
+
78
+ private
79
+ def _max_width(things)
80
+ things.compact.map(&:size).max || 0
81
+ end
82
+
83
+ def _rebuild_colorless_cache
84
+ @colorless_cache = {}
85
+ @plain_items = []
86
+ items.map do |e|
87
+ plain = Pry::Helpers::Text.strip_color(e)
88
+ @colorless_cache[plain] = e
89
+ @plain_items << plain
90
+ end
91
+ end
92
+
93
+ def _recolumn
94
+ @rows_without_colors = []
95
+ return if items.size.zero?
96
+ row_count = (items.size.to_f/column_count).ceil
97
+ row_count.times do |i|
98
+ row_indices = (0...column_count).map{|e| row_count*e+i}
99
+ @rows_without_colors << row_indices.map{|e| @plain_items[e]}
100
+ end
101
+ end
102
+
103
+ def _recall_color_for thing
104
+ @colorless_cache[thing]
105
+ end
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,107 @@
1
+ class Pry
2
+ module Helpers
3
+
4
+ # The methods defined on {Text} are available to custom commands via {Pry::Command#text}.
5
+ module Text
6
+
7
+ COLORS =
8
+ {
9
+ "black" => 0,
10
+ "red" => 1,
11
+ "green" => 2,
12
+ "yellow" => 3,
13
+ "blue" => 4,
14
+ "purple" => 5,
15
+ "magenta" => 5,
16
+ "cyan" => 6,
17
+ "white" => 7
18
+ }
19
+
20
+ class << self
21
+
22
+ COLORS.each_pair do |color, value|
23
+ define_method color do |text|
24
+ "\033[0;#{30+value}m#{text}\033[0m"
25
+ end
26
+
27
+ define_method "bright_#{color}" do |text|
28
+ "\033[1;#{30+value}m#{text}\033[0m"
29
+ end
30
+ end
31
+
32
+ # Remove any color codes from _text_.
33
+ #
34
+ # @param [String, #to_s] text
35
+ # @return [String] _text_ stripped of any color codes.
36
+ def strip_color(text)
37
+ text.to_s.gsub(/\e\[.*?(\d)+m/ , '')
38
+ end
39
+
40
+ # Returns _text_ as bold text for use on a terminal.
41
+ #
42
+ # @param [String, #to_s] text
43
+ # @return [String] _text_
44
+ def bold(text)
45
+ "\e[1m#{text}\e[0m"
46
+ end
47
+
48
+ # Returns `text` in the default foreground colour.
49
+ # Use this instead of "black" or "white" when you mean absence of colour.
50
+ #
51
+ # @param [String, #to_s] text
52
+ # @return [String]
53
+ def default(text)
54
+ text.to_s
55
+ end
56
+ alias_method :bright_default, :bold
57
+
58
+ # Executes the block with `Pry.config.color` set to false.
59
+ # @yield
60
+ # @return [void]
61
+ def no_color(&block)
62
+ boolean = Pry.config.color
63
+ Pry.config.color = false
64
+ yield
65
+ ensure
66
+ Pry.config.color = boolean
67
+ end
68
+
69
+ # Executes the block with `Pry.config.pager` set to false.
70
+ # @yield
71
+ # @return [void]
72
+ def no_pager(&block)
73
+ boolean = Pry.config.pager
74
+ Pry.config.pager = false
75
+ yield
76
+ ensure
77
+ Pry.config.pager = boolean
78
+ end
79
+
80
+ # Returns _text_ in a numbered list, beginning at _offset_.
81
+ #
82
+ # @param [#each_line] text
83
+ # @param [Fixnum] offset
84
+ # @return [String]
85
+ def with_line_numbers(text, offset, color=:blue)
86
+ lines = text.each_line.to_a
87
+ max_width = (offset + lines.count).to_s.length
88
+ lines.each_with_index.map do |line, index|
89
+ adjusted_index = (index + offset).to_s.rjust(max_width)
90
+ "#{self.send(color, adjusted_index)}: #{line}"
91
+ end.join
92
+ end
93
+
94
+ # Returns _text_ indented by _chars_ spaces.
95
+ #
96
+ # @param [String] text
97
+ # @param [Fixnum] chars
98
+ def indent(text, chars)
99
+ text.lines.map { |l| "#{' ' * chars}#{l}" }.join
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
107
+
@@ -0,0 +1,125 @@
1
+ class Pry
2
+ # The History class is responsible for maintaining the user's input history,
3
+ # both internally and within Readline.
4
+ class History
5
+ attr_accessor :loader, :saver, :pusher, :clearer
6
+
7
+ # @return [Fixnum] Number of lines in history when Pry first loaded.
8
+ attr_reader :original_lines
9
+
10
+ def initialize(options={})
11
+ @history = []
12
+ @original_lines = 0
13
+ @file_path = options[:file_path]
14
+ restore_default_behavior
15
+ end
16
+
17
+ # Assign the default methods for loading, saving, pushing, and clearing.
18
+ def restore_default_behavior
19
+ Pry.config.input # force Readline to load if applicable
20
+
21
+ @loader = method(:read_from_file)
22
+ @saver = method(:save_to_file)
23
+
24
+ if defined?(Readline)
25
+ @pusher = method(:push_to_readline)
26
+ @clearer = method(:clear_readline)
27
+ else
28
+ @pusher = proc { }
29
+ @clearer = proc { }
30
+ end
31
+ end
32
+
33
+ # Load the input history using `History.loader`.
34
+ # @return [Integer] The number of lines loaded
35
+ def load
36
+ @loader.call do |line|
37
+ @pusher.call(line.chomp)
38
+ @history << line.chomp
39
+ @original_lines += 1
40
+ end
41
+ end
42
+
43
+ # Add a line to the input history, ignoring blank and duplicate lines.
44
+ # @param [String] line
45
+ # @return [String] The same line that was passed in
46
+ def push(line)
47
+ unless line.empty? || (@history.last && line == @history.last)
48
+ @pusher.call(line)
49
+ @history << line
50
+ @saver.call(line) if Pry.config.history.should_save
51
+ end
52
+ line
53
+ end
54
+ alias << push
55
+
56
+ # Clear this session's history. This won't affect the contents of the
57
+ # history file.
58
+ def clear
59
+ @clearer.call
60
+ @history = []
61
+ end
62
+
63
+ # @return [Fixnum] The number of lines in history.
64
+ def history_line_count
65
+ @history.count
66
+ end
67
+
68
+ # @return [Fixnum] The number of lines in history from just this session.
69
+ def session_line_count
70
+ @history.count - @original_lines
71
+ end
72
+
73
+ # Return an Array containing all stored history.
74
+ # @return [Array<String>] An Array containing all lines of history loaded
75
+ # or entered by the user in the current session.
76
+ def to_a
77
+ @history.dup
78
+ end
79
+
80
+ private
81
+
82
+ # The default loader. Yields lines from `Pry.history.config.file`.
83
+ def read_from_file
84
+ filename = File.expand_path(Pry.config.history.file)
85
+
86
+ if File.exists?(filename)
87
+ File.foreach(filename) { |line| yield(line) }
88
+ end
89
+ rescue => error
90
+ warn "History file not loaded: #{error.message}"
91
+ end
92
+
93
+ # The default pusher. Appends the given line to Readline::HISTORY.
94
+ # @param [String] line
95
+ def push_to_readline(line)
96
+ Readline::HISTORY << line
97
+ end
98
+
99
+ # The default clearer. Clears Readline::HISTORY.
100
+ def clear_readline
101
+ Readline::HISTORY.shift until Readline::HISTORY.empty?
102
+ end
103
+
104
+ # The default saver. Appends the given line to `Pry.history.config.file`.
105
+ def save_to_file(line)
106
+ history_file.puts line if history_file
107
+ end
108
+
109
+ # The history file, opened for appending.
110
+ def history_file
111
+ if defined?(@history_file)
112
+ @history_file
113
+ else
114
+ @history_file = File.open(file_path, 'a', 0600).tap { |f| f.sync = true }
115
+ end
116
+ rescue Errno::EACCES
117
+ warn 'History not saved; unable to open your history file for writing.'
118
+ @history_file = false
119
+ end
120
+
121
+ def file_path
122
+ @file_path || Pry.config.history.file
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,121 @@
1
+ class Pry
2
+ # A history array is an array to which you can only add elements. Older
3
+ # entries are removed progressively, so that the array never contains more than
4
+ # N elements.
5
+ #
6
+ # History arrays are used by Pry to store the output of the last commands.
7
+ #
8
+ # @example
9
+ # ary = Pry::HistoryArray.new 10
10
+ # ary << 1 << 2 << 3
11
+ # ary[0] # => 1
12
+ # ary[1] # => 2
13
+ # 10.times { |n| ary << n }
14
+ # ary[0] # => nil
15
+ # ary[-1] # => 9
16
+ class HistoryArray
17
+ include Enumerable
18
+
19
+ # @param [Integer] size Maximum amount of objects in the array
20
+ def initialize(size)
21
+ @max_size = size
22
+
23
+ @hash = {}
24
+ @count = 0
25
+ end
26
+
27
+ # Pushes an object at the end of the array
28
+ # @param [Object] value Object to be added
29
+ def <<(value)
30
+ @hash[@count] = value
31
+
32
+ if @hash.size > max_size
33
+ @hash.delete(@count - max_size)
34
+ end
35
+
36
+ @count += 1
37
+
38
+ self
39
+ end
40
+
41
+ # @overload [](index)
42
+ # @param [Integer] index Index of the item to access.
43
+ # @return [Object, nil] Item at that index or nil if it has been removed.
44
+ # @overload [](index, size)
45
+ # @param [Integer] index Index of the first item to access.
46
+ # @param [Integer] size Amount of items to access
47
+ # @return [Array, nil] The selected items. Nil if index is greater than
48
+ # the size of the array.
49
+ # @overload [](range)
50
+ # @param [Range<Integer>] range Range of indices to access.
51
+ # @return [Array, nil] The selected items. Nil if index is greater than
52
+ # the size of the array.
53
+ def [](index_or_range, size = nil)
54
+ if index_or_range.is_a? Integer
55
+ index = convert_index(index_or_range)
56
+
57
+ if size
58
+ end_index = index + size
59
+ index > @count ? nil : (index...[end_index, @count].min).map do |n|
60
+ @hash[n]
61
+ end
62
+ else
63
+ @hash[index]
64
+ end
65
+ else
66
+ range = convert_range(index_or_range)
67
+ range.begin > @count ? nil : range.map { |n| @hash[n] }
68
+ end
69
+ end
70
+
71
+ # @return [Integer] Amount of objects in the array
72
+ def size
73
+ @count
74
+ end
75
+ alias count size
76
+ alias length size
77
+
78
+ def empty?
79
+ size == 0
80
+ end
81
+
82
+ def each
83
+ ((@count - size)...@count).each do |n|
84
+ yield @hash[n]
85
+ end
86
+ end
87
+
88
+ def to_a
89
+ ((@count - size)...@count).map { |n| @hash[n] }
90
+ end
91
+
92
+ # Returns [Hash] copy of the internal @hash history
93
+ def to_h
94
+ @hash.dup
95
+ end
96
+
97
+ def pop!
98
+ @hash.delete @count - 1
99
+ @count -= 1
100
+ end
101
+
102
+ def inspect
103
+ "#<#{self.class} size=#{size} first=#{@count - size} max_size=#{max_size}>"
104
+ end
105
+
106
+ # @return [Integer] Maximum amount of objects in the array
107
+ attr_reader :max_size
108
+
109
+ private
110
+ def convert_index(n)
111
+ n >= 0 ? n : @count + n
112
+ end
113
+
114
+ def convert_range(range)
115
+ end_index = convert_index(range.end)
116
+ end_index += 1 unless range.exclude_end?
117
+
118
+ Range.new(convert_index(range.begin), [end_index, @count].min, true)
119
+ end
120
+ end
121
+ end