pry 0.10.4-java → 0.11.0-java

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -18
  3. data/LICENSE +1 -1
  4. data/README.md +32 -31
  5. data/bin/pry +3 -7
  6. data/lib/pry.rb +4 -4
  7. data/lib/pry/basic_object.rb +6 -0
  8. data/lib/pry/cli.rb +39 -34
  9. data/lib/pry/code.rb +6 -1
  10. data/lib/pry/code/code_file.rb +8 -2
  11. data/lib/pry/code_object.rb +23 -0
  12. data/lib/pry/color_printer.rb +20 -11
  13. data/lib/pry/command.rb +40 -16
  14. data/lib/pry/command_set.rb +9 -2
  15. data/lib/pry/commands/cat/exception_formatter.rb +11 -10
  16. data/lib/pry/commands/cat/file_formatter.rb +7 -3
  17. data/lib/pry/commands/code_collector.rb +16 -14
  18. data/lib/pry/commands/easter_eggs.rb +9 -9
  19. data/lib/pry/commands/edit.rb +7 -3
  20. data/lib/pry/commands/edit/file_and_line_locator.rb +1 -1
  21. data/lib/pry/commands/find_method.rb +1 -1
  22. data/lib/pry/commands/gem_open.rb +1 -1
  23. data/lib/pry/commands/gem_readme.rb +25 -0
  24. data/lib/pry/commands/gem_search.rb +40 -0
  25. data/lib/pry/commands/hist.rb +2 -2
  26. data/lib/pry/commands/jump_to.rb +7 -7
  27. data/lib/pry/commands/ls.rb +3 -1
  28. data/lib/pry/commands/ls/constants.rb +12 -1
  29. data/lib/pry/commands/ls/formatter.rb +1 -0
  30. data/lib/pry/commands/ls/jruby_hacks.rb +2 -2
  31. data/lib/pry/commands/ls/self_methods.rb +2 -0
  32. data/lib/pry/commands/play.rb +2 -2
  33. data/lib/pry/commands/reload_code.rb +2 -2
  34. data/lib/pry/commands/ri.rb +4 -0
  35. data/lib/pry/commands/shell_command.rb +34 -8
  36. data/lib/pry/commands/show_info.rb +10 -2
  37. data/lib/pry/commands/watch_expression/expression.rb +1 -1
  38. data/lib/pry/commands/whereami.rb +7 -6
  39. data/lib/pry/config.rb +3 -16
  40. data/lib/pry/config/behavior.rb +140 -49
  41. data/lib/pry/config/default.rb +21 -33
  42. data/lib/pry/config/memoization.rb +44 -0
  43. data/lib/pry/core_extensions.rb +12 -2
  44. data/lib/pry/editor.rb +1 -1
  45. data/lib/pry/exceptions.rb +1 -1
  46. data/lib/pry/forwardable.rb +23 -0
  47. data/lib/pry/helpers/base_helpers.rb +6 -10
  48. data/lib/pry/helpers/documentation_helpers.rb +1 -0
  49. data/lib/pry/helpers/options_helpers.rb +1 -1
  50. data/lib/pry/helpers/text.rb +69 -75
  51. data/lib/pry/history.rb +22 -1
  52. data/lib/pry/history_array.rb +1 -1
  53. data/lib/pry/hooks.rb +48 -107
  54. data/lib/pry/indent.rb +6 -2
  55. data/lib/pry/input_completer.rb +138 -120
  56. data/lib/pry/last_exception.rb +2 -2
  57. data/lib/pry/method.rb +15 -15
  58. data/lib/pry/method/disowned.rb +1 -0
  59. data/lib/pry/method/patcher.rb +0 -3
  60. data/lib/pry/output.rb +37 -38
  61. data/lib/pry/pager.rb +11 -8
  62. data/lib/pry/plugins.rb +20 -5
  63. data/lib/pry/pry_class.rb +30 -4
  64. data/lib/pry/pry_instance.rb +8 -6
  65. data/lib/pry/repl.rb +38 -8
  66. data/lib/pry/repl_file_loader.rb +1 -1
  67. data/lib/pry/rubygem.rb +3 -1
  68. data/lib/pry/slop.rb +661 -0
  69. data/lib/pry/slop/LICENSE +20 -0
  70. data/lib/pry/slop/commands.rb +196 -0
  71. data/lib/pry/slop/option.rb +208 -0
  72. data/lib/pry/terminal.rb +16 -5
  73. data/lib/pry/test/helper.rb +12 -3
  74. data/lib/pry/version.rb +1 -1
  75. data/lib/pry/wrapped_module.rb +7 -7
  76. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +7 -13
  77. metadata +14 -19
@@ -2,130 +2,201 @@ module Pry::Config::Behavior
2
2
  ASSIGNMENT = "=".freeze
3
3
  NODUP = [TrueClass, FalseClass, NilClass, Symbol, Numeric, Module, Proc].freeze
4
4
  INSPECT_REGEXP = /#{Regexp.escape "default=#<"}/
5
+ ReservedKeyError = Class.new(RuntimeError)
5
6
 
6
7
  module Builder
7
- def from_hash(hash, default = nil)
8
+ #
9
+ # @param [Hash] attributes
10
+ # a hash to initialize an instance of self with.
11
+ #
12
+ # @param [Pry::Config, nil] default
13
+ # a default, or nil for none.
14
+ #
15
+ # @return [Pry::Config]
16
+ # returns an instance of self.
17
+ #
18
+ def from_hash(attributes, default = nil)
8
19
  new(default).tap do |config|
9
- config.merge!(hash)
20
+ attributes.each do |key,value|
21
+ config[key] = Hash === value ? from_hash(value, nil) : value
22
+ end
10
23
  end
11
24
  end
12
25
  end
13
26
 
14
27
  def self.included(klass)
15
- unless defined?(RESERVED_KEYS)
16
- const_set :RESERVED_KEYS, instance_methods(false).map(&:to_s).freeze
17
- end
18
28
  klass.extend(Builder)
19
29
  end
20
30
 
21
31
  def initialize(default = Pry.config)
22
32
  @default = default
23
33
  @lookup = {}
34
+ @reserved_keys = methods.map(&:to_s).freeze
24
35
  end
25
36
 
26
37
  #
27
38
  # @return [Pry::Config::Behavior]
28
- # returns the default used if a matching value for a key isn't found in self
39
+ # returns the default used incase a key isn't found in self.
29
40
  #
30
41
  def default
31
42
  @default
32
43
  end
33
44
 
45
+ #
46
+ # @param [String] key
47
+ # a key (as a String)
48
+ #
49
+ # @return [Object, BasicObject]
50
+ # returns an object from self or one of its defaults.
51
+ #
34
52
  def [](key)
35
- @lookup[key.to_s]
53
+ key = key.to_s
54
+ key?(key) ? @lookup[key] : (@default and @default[key])
36
55
  end
37
56
 
57
+ #
58
+ # Add a key and value pair to self.
59
+ #
60
+ # @param [String] key
61
+ # a key (as a String).
62
+ #
63
+ # @param [Object,BasicObject] value
64
+ # a value.
65
+ #
66
+ # @raise [Pry::Config::ReservedKeyError]
67
+ # when 'key' is a reserved key name.
68
+ #
38
69
  def []=(key, value)
39
70
  key = key.to_s
40
- if RESERVED_KEYS.include?(key)
41
- raise ArgumentError, "few things are reserved by pry, but using '#{key}' as a configuration key is."
71
+ if @reserved_keys.include?(key)
72
+ raise ReservedKeyError, "It is not possible to use '#{key}' as a key name, please choose a different key name."
42
73
  end
43
- @lookup[key] = value
74
+ __push(key,value)
44
75
  end
45
76
 
46
- def method_missing(name, *args, &block)
47
- key = name.to_s
48
- if key[-1] == ASSIGNMENT
49
- short_key = key[0..-2]
50
- self[short_key] = args[0]
51
- elsif key?(key)
52
- self[key]
53
- elsif @default.respond_to?(name)
54
- value = @default.public_send(name, *args, &block)
55
- # FIXME: refactor Pry::Hook so that it stores config on the config object,
56
- # so that we can use the normal strategy.
57
- self[key] = value = value.dup if key == 'hooks'
58
- value
59
- else
60
- nil
61
- end
77
+ #
78
+ # Removes a key from self.
79
+ #
80
+ # @param [String] key
81
+ # a key (as a String)
82
+ #
83
+ # @return [void]
84
+ #
85
+ def forget(key)
86
+ key = key.to_s
87
+ __remove(key)
62
88
  end
63
89
 
90
+ #
91
+ # @param [Hash, #to_h, #to_hash] other
92
+ # a hash to merge into self.
93
+ #
94
+ # @return [void]
95
+ #
64
96
  def merge!(other)
65
- other = try_convert_to_hash(other)
97
+ other = __try_convert_to_hash(other)
66
98
  raise TypeError, "unable to convert argument into a Hash" unless other
67
99
  other.each do |key, value|
68
100
  self[key] = value
69
101
  end
70
102
  end
71
103
 
104
+ #
105
+ # @param [Hash, #to_h, #to_hash] other
106
+ # a hash to compare against the lookup table of self.
107
+ #
72
108
  def ==(other)
73
- @lookup == try_convert_to_hash(other)
109
+ @lookup == __try_convert_to_hash(other)
74
110
  end
75
111
  alias_method :eql?, :==
76
112
 
77
- def respond_to_missing?(key, include_private=false)
78
- key?(key) or @default.respond_to?(key) or super(key, include_private)
79
- end
80
-
113
+ #
114
+ # @param [String] key
115
+ # a key (as a String)
116
+ #
117
+ # @return [Boolean]
118
+ # returns true when "key" is a member of self.
119
+ #
81
120
  def key?(key)
82
121
  key = key.to_s
83
122
  @lookup.key?(key)
84
123
  end
85
124
 
125
+ #
126
+ # Clear the lookup table of self.
127
+ #
128
+ # @return [void]
129
+ #
86
130
  def clear
87
131
  @lookup.clear
88
132
  true
89
133
  end
90
- alias_method :refresh, :clear
91
-
92
- def forget(key)
93
- @lookup.delete(key.to_s)
94
- end
95
134
 
135
+ #
136
+ # @return [Array<String>]
137
+ # returns an array of keys in self.
138
+ #
96
139
  def keys
97
140
  @lookup.keys
98
141
  end
99
142
 
143
+ def eager_load!
144
+ default = @default
145
+ while default
146
+ default.memoized_methods.each {|method| self[key] = default.public_send(key)} if default.respond_to?(:memoized_methods)
147
+ default = @default.default
148
+ end
149
+ end
150
+
151
+ def last_default
152
+ last = @default
153
+ last = last.default while last and last.default
154
+ last
155
+ end
156
+
157
+ #
158
+ # @return [Hash]
159
+ # returns a duplicate copy of the lookup table used by self.
160
+ #
100
161
  def to_hash
101
162
  @lookup.dup
102
163
  end
103
164
  alias_method :to_h, :to_hash
104
165
 
105
-
106
166
  def inspect
107
167
  key_str = keys.map { |key| "'#{key}'" }.join(",")
108
- "#<#{_clip_inspect(self)} local_keys=[#{key_str}] default=#{@default.inspect}>"
168
+ "#<#{__clip_inspect(self)} keys=[#{key_str}] default=#{@default.inspect}>"
109
169
  end
110
170
 
111
171
  def pretty_print(q)
112
172
  q.text inspect[1..-1].gsub(INSPECT_REGEXP, "default=<")
113
173
  end
114
174
 
115
- private
116
- def _clip_inspect(obj)
117
- "#{obj.class}:0x%x" % obj.object_id << 1
118
- end
119
-
120
- def _dup(value)
121
- if NODUP.any? { |klass| klass === value }
122
- value
175
+ def method_missing(name, *args, &block)
176
+ key = name.to_s
177
+ if key[-1] == ASSIGNMENT
178
+ short_key = key[0..-2]
179
+ self[short_key] = args[0]
180
+ elsif key?(key)
181
+ self[key]
182
+ elsif @default.respond_to?(name)
183
+ value = @default.public_send(name, *args, &block)
184
+ self[key] = __dup(value)
123
185
  else
124
- value.dup
186
+ nil
125
187
  end
126
188
  end
127
189
 
128
- def try_convert_to_hash(obj)
190
+ def respond_to_missing?(key, include_all=false)
191
+ key?(key) or @default.respond_to?(key) or super(key, include_all)
192
+ end
193
+
194
+ private
195
+ def __clip_inspect(obj)
196
+ "#{obj.class}:0x%x" % obj.object_id
197
+ end
198
+
199
+ def __try_convert_to_hash(obj)
129
200
  if Hash === obj
130
201
  obj
131
202
  elsif obj.respond_to?(:to_h)
@@ -136,4 +207,24 @@ private
136
207
  nil
137
208
  end
138
209
  end
210
+
211
+ def __dup(value)
212
+ if NODUP.any? { |klass| klass === value }
213
+ value
214
+ else
215
+ value.dup
216
+ end
217
+ end
218
+
219
+ def __push(key,value)
220
+ unless singleton_class.method_defined? key
221
+ define_singleton_method(key) { self[key] }
222
+ define_singleton_method("#{key}=") { |val| @lookup[key] = val }
223
+ end
224
+ @lookup[key] = value
225
+ end
226
+
227
+ def __remove(key)
228
+ @lookup.delete(key)
229
+ end
139
230
  end
@@ -1,12 +1,13 @@
1
1
  class Pry::Config::Default
2
2
  include Pry::Config::Behavior
3
+ include Pry::Config::Memoization
3
4
 
4
- default = {
5
+ def_memoized({
5
6
  input: proc {
6
7
  lazy_readline
7
8
  },
8
9
  output: proc {
9
- $stdout
10
+ $stdout.tap { |out| out.sync = true }
10
11
  },
11
12
  commands: proc {
12
13
  Pry::Commands
@@ -110,43 +111,30 @@ class Pry::Config::Default
110
111
  completer: proc {
111
112
  require "pry/input_completer"
112
113
  Pry::InputCompleter
114
+ },
115
+ gist: proc {
116
+ Pry::Config.from_hash({inspecter: proc(&:pretty_inspect)}, nil)
117
+ },
118
+ history: proc {
119
+ Pry::Config.from_hash({should_save: true, should_load: true}, nil).tap do |history|
120
+ history.file = File.expand_path("~/.pry_history") rescue nil
121
+ if history.file.nil?
122
+ self.should_load_rc = false
123
+ history.should_save = false
124
+ history.should_load = false
125
+ end
126
+ end
127
+ },
128
+ exec_string: proc {
129
+ ""
113
130
  }
114
- }
131
+ })
115
132
 
116
133
  def initialize
117
134
  super(nil)
118
- configure_gist
119
- configure_history
120
- end
121
-
122
- default.each do |key, value|
123
- define_method(key) do
124
- if default[key].equal?(value)
125
- default[key] = instance_eval(&value)
126
- end
127
- default[key]
128
- end
129
- end
130
-
131
- private
132
- # TODO:
133
- # all of this configure_* stuff is a relic of old code.
134
- # we should try move this code to being command-local.
135
- def configure_gist
136
- self["gist"] = Pry::Config.from_hash(inspecter: proc(&:pretty_inspect))
137
- end
138
-
139
- def configure_history
140
- self["history"] = Pry::Config.from_hash "should_save" => true,
141
- "should_load" => true
142
- history.file = File.expand_path("~/.pry_history") rescue nil
143
- if history.file.nil?
144
- self.should_load_rc = false
145
- history.should_save = false
146
- history.should_load = false
147
- end
148
135
  end
149
136
 
137
+ private
150
138
  def lazy_readline
151
139
  require 'readline'
152
140
  Readline
@@ -0,0 +1,44 @@
1
+ module Pry::Config::Memoization
2
+ MEMOIZED_METHODS = Hash.new {|h,k| h[k] = [] }
3
+
4
+ module ClassMethods
5
+ #
6
+ # Defines one or more methods who return a constant value after being
7
+ # called once.
8
+ #
9
+ # @example
10
+ # class Foo
11
+ # include Pry::Config::Memoization
12
+ # def_memoized({
13
+ # foo: proc {1+10},
14
+ # bar: proc{"aaa"<<"a"}
15
+ # })
16
+ # end
17
+ #
18
+ # @param [{String => Proc}] method_table
19
+ #
20
+ # @return [void]
21
+ #
22
+ def def_memoized(method_table)
23
+ method_table.each do |method_name, method|
24
+ define_method(method_name) do
25
+ method_table[method_name] = instance_eval(&method) if method_table[method_name].equal? method
26
+ method_table[method_name]
27
+ end
28
+ end
29
+ MEMOIZED_METHODS[self] |= method_table.keys
30
+ end
31
+ end
32
+
33
+ def self.included(mod)
34
+ mod.extend(ClassMethods)
35
+ end
36
+
37
+ #
38
+ # @return [Array<Symbol>]
39
+ # Returns the names of methods that have been defined by {ClassMethods#def_memoized}.
40
+ #
41
+ def memoized_methods
42
+ MEMOIZED_METHODS[self.class]
43
+ end
44
+ end
@@ -68,12 +68,22 @@ class Object
68
68
  def __binding__
69
69
  # If you ever feel like changing this method, be careful about variables
70
70
  # that you use. They shouldn't be inserted into the binding that will
71
- # eventually be returning.
71
+ # eventually be returned.
72
72
 
73
73
  # When you're cd'd into a class, methods you define should be added to it.
74
74
  if is_a?(Module)
75
+ # A special case, for JRuby.
76
+ # Module.new.class_eval("binding") has different behaviour than CRuby,
77
+ # where this is not needed: class_eval("binding") vs class_eval{binding}.
78
+ # Using a block works around the difference of behaviour on JRuby.
79
+ # The scope is clear of local variabless. Don't add any.
80
+ #
81
+ # This fixes the following two spec failures, at https://travis-ci.org/pry/pry/jobs/274470002
82
+ # 1) ./spec/pry_spec.rb:360:in `block in (root)'
83
+ # 2) ./spec/pry_spec.rb:366:in `block in (root)'
84
+ return class_eval {binding} if Pry::Helpers::BaseHelpers.jruby? and self.name == nil
75
85
  # class_eval sets both self and the default definee to this class.
76
- return class_eval "binding"
86
+ return class_eval("binding")
77
87
  end
78
88
 
79
89
  unless respond_to?(:__pry__)
data/lib/pry/editor.rb CHANGED
@@ -44,7 +44,7 @@ class Pry
44
44
  _pry_.config.editor.call(*args)
45
45
  else
46
46
  sanitized_file = if windows?
47
- file.gsub(/\//, '\\')
47
+ file
48
48
  else
49
49
  Shellwords.escape(file)
50
50
  end
@@ -52,7 +52,7 @@ class Pry
52
52
  def self.===(exception)
53
53
  ["can't modify frozen class/module",
54
54
  "can't modify frozen Class",
55
- "can't modify frozen object"
55
+ "can't modify frozen object",
56
56
  ].include?(exception.message)
57
57
  end
58
58
  end
@@ -0,0 +1,23 @@
1
+ class Pry
2
+ module Forwardable
3
+ require 'forwardable'
4
+ include ::Forwardable
5
+
6
+ #
7
+ # Since Ruby 2.4, Forwardable will print a warning when
8
+ # calling a method that is private on a delegate, and
9
+ # in the future it could be an error: https://bugs.ruby-lang.org/issues/12782#note-3
10
+ #
11
+ # That's why we revert to a custom implementation for delegating one
12
+ # private method to another.
13
+ #
14
+ def def_private_delegators(target, *private_delegates)
15
+ private_delegates.each do |private_delegate|
16
+ define_method(private_delegate) do |*a, &b|
17
+ instance_variable_get(target).__send__(private_delegate, *a, &b)
18
+ end
19
+ end
20
+ class_eval { private(*private_delegates) }
21
+ end
22
+ end
23
+ end