pry 0.12.2-java → 0.13.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 (158) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +110 -1
  3. data/LICENSE +1 -1
  4. data/README.md +331 -269
  5. data/bin/pry +5 -0
  6. data/lib/pry.rb +133 -119
  7. data/lib/pry/basic_object.rb +8 -4
  8. data/lib/pry/block_command.rb +22 -0
  9. data/lib/pry/class_command.rb +194 -0
  10. data/lib/pry/cli.rb +40 -31
  11. data/lib/pry/code.rb +39 -27
  12. data/lib/pry/code/code_file.rb +28 -24
  13. data/lib/pry/code/code_range.rb +4 -2
  14. data/lib/pry/code/loc.rb +15 -8
  15. data/lib/pry/code_object.rb +40 -38
  16. data/lib/pry/color_printer.rb +47 -46
  17. data/lib/pry/command.rb +166 -369
  18. data/lib/pry/command_set.rb +76 -73
  19. data/lib/pry/command_state.rb +31 -0
  20. data/lib/pry/commands/amend_line.rb +86 -81
  21. data/lib/pry/commands/bang.rb +18 -14
  22. data/lib/pry/commands/bang_pry.rb +15 -11
  23. data/lib/pry/commands/cat.rb +61 -54
  24. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  25. data/lib/pry/commands/cat/exception_formatter.rb +71 -60
  26. data/lib/pry/commands/cat/file_formatter.rb +55 -49
  27. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  28. data/lib/pry/commands/cd.rb +40 -35
  29. data/lib/pry/commands/change_inspector.rb +29 -22
  30. data/lib/pry/commands/change_prompt.rb +44 -39
  31. data/lib/pry/commands/clear_screen.rb +16 -10
  32. data/lib/pry/commands/code_collector.rb +148 -133
  33. data/lib/pry/commands/disable_pry.rb +23 -19
  34. data/lib/pry/commands/easter_eggs.rb +19 -30
  35. data/lib/pry/commands/edit.rb +184 -161
  36. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  37. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  38. data/lib/pry/commands/exit.rb +39 -35
  39. data/lib/pry/commands/exit_all.rb +24 -20
  40. data/lib/pry/commands/exit_program.rb +20 -16
  41. data/lib/pry/commands/find_method.rb +168 -160
  42. data/lib/pry/commands/fix_indent.rb +16 -12
  43. data/lib/pry/commands/help.rb +140 -133
  44. data/lib/pry/commands/hist.rb +151 -150
  45. data/lib/pry/commands/import_set.rb +20 -16
  46. data/lib/pry/commands/jump_to.rb +25 -21
  47. data/lib/pry/commands/list_inspectors.rb +35 -28
  48. data/lib/pry/commands/ls.rb +124 -102
  49. data/lib/pry/commands/ls/constants.rb +59 -42
  50. data/lib/pry/commands/ls/formatter.rb +50 -46
  51. data/lib/pry/commands/ls/globals.rb +38 -34
  52. data/lib/pry/commands/ls/grep.rb +17 -13
  53. data/lib/pry/commands/ls/instance_vars.rb +29 -27
  54. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  55. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  56. data/lib/pry/commands/ls/local_names.rb +26 -22
  57. data/lib/pry/commands/ls/local_vars.rb +38 -28
  58. data/lib/pry/commands/ls/ls_entity.rb +47 -51
  59. data/lib/pry/commands/ls/methods.rb +44 -43
  60. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  61. data/lib/pry/commands/ls/self_methods.rb +23 -22
  62. data/lib/pry/commands/nesting.rb +21 -17
  63. data/lib/pry/commands/play.rb +93 -82
  64. data/lib/pry/commands/pry_backtrace.rb +24 -17
  65. data/lib/pry/commands/pry_version.rb +15 -11
  66. data/lib/pry/commands/raise_up.rb +27 -22
  67. data/lib/pry/commands/reload_code.rb +60 -48
  68. data/lib/pry/commands/reset.rb +16 -12
  69. data/lib/pry/commands/ri.rb +55 -45
  70. data/lib/pry/commands/save_file.rb +45 -43
  71. data/lib/pry/commands/shell_command.rb +51 -51
  72. data/lib/pry/commands/shell_mode.rb +21 -17
  73. data/lib/pry/commands/show_doc.rb +81 -68
  74. data/lib/pry/commands/show_info.rb +189 -171
  75. data/lib/pry/commands/show_input.rb +16 -11
  76. data/lib/pry/commands/show_source.rb +109 -45
  77. data/lib/pry/commands/stat.rb +35 -31
  78. data/lib/pry/commands/switch_to.rb +21 -15
  79. data/lib/pry/commands/toggle_color.rb +20 -16
  80. data/lib/pry/commands/watch_expression.rb +89 -86
  81. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  82. data/lib/pry/commands/whereami.rb +156 -148
  83. data/lib/pry/commands/wtf.rb +75 -50
  84. data/lib/pry/config.rb +311 -25
  85. data/lib/pry/config/attributable.rb +22 -0
  86. data/lib/pry/config/lazy_value.rb +29 -0
  87. data/lib/pry/config/memoized_value.rb +34 -0
  88. data/lib/pry/config/value.rb +24 -0
  89. data/lib/pry/control_d_handler.rb +28 -0
  90. data/lib/pry/core_extensions.rb +9 -7
  91. data/lib/pry/editor.rb +48 -21
  92. data/lib/pry/env.rb +18 -0
  93. data/lib/pry/exception_handler.rb +43 -0
  94. data/lib/pry/exceptions.rb +13 -16
  95. data/lib/pry/forwardable.rb +5 -1
  96. data/lib/pry/helpers.rb +2 -0
  97. data/lib/pry/helpers/base_helpers.rb +68 -197
  98. data/lib/pry/helpers/command_helpers.rb +50 -61
  99. data/lib/pry/helpers/documentation_helpers.rb +20 -13
  100. data/lib/pry/helpers/options_helpers.rb +14 -7
  101. data/lib/pry/helpers/platform.rb +7 -5
  102. data/lib/pry/helpers/table.rb +33 -26
  103. data/lib/pry/helpers/text.rb +17 -14
  104. data/lib/pry/history.rb +48 -56
  105. data/lib/pry/hooks.rb +21 -12
  106. data/lib/pry/indent.rb +54 -50
  107. data/lib/pry/input_completer.rb +248 -230
  108. data/lib/pry/input_lock.rb +8 -9
  109. data/lib/pry/inspector.rb +36 -24
  110. data/lib/pry/last_exception.rb +45 -45
  111. data/lib/pry/method.rb +141 -94
  112. data/lib/pry/method/disowned.rb +16 -4
  113. data/lib/pry/method/patcher.rb +12 -3
  114. data/lib/pry/method/weird_method_locator.rb +68 -44
  115. data/lib/pry/object_path.rb +33 -25
  116. data/lib/pry/output.rb +121 -35
  117. data/lib/pry/pager.rb +41 -42
  118. data/lib/pry/plugins.rb +25 -8
  119. data/lib/pry/prompt.rb +123 -54
  120. data/lib/pry/pry_class.rb +61 -98
  121. data/lib/pry/pry_instance.rb +217 -215
  122. data/lib/pry/repl.rb +18 -22
  123. data/lib/pry/repl_file_loader.rb +27 -21
  124. data/lib/pry/ring.rb +11 -6
  125. data/lib/pry/slop.rb +574 -563
  126. data/lib/pry/slop/commands.rb +164 -169
  127. data/lib/pry/slop/option.rb +172 -168
  128. data/lib/pry/syntax_highlighter.rb +26 -0
  129. data/lib/pry/system_command_handler.rb +17 -0
  130. data/lib/pry/testable.rb +59 -61
  131. data/lib/pry/testable/evalable.rb +21 -12
  132. data/lib/pry/testable/mockable.rb +18 -10
  133. data/lib/pry/testable/pry_tester.rb +71 -56
  134. data/lib/pry/testable/utility.rb +29 -21
  135. data/lib/pry/testable/variables.rb +49 -43
  136. data/lib/pry/version.rb +3 -1
  137. data/lib/pry/warning.rb +27 -0
  138. data/lib/pry/wrapped_module.rb +51 -42
  139. data/lib/pry/wrapped_module/candidate.rb +21 -14
  140. metadata +31 -30
  141. data/lib/pry/commands.rb +0 -6
  142. data/lib/pry/commands/disabled_commands.rb +0 -2
  143. data/lib/pry/commands/gem_cd.rb +0 -26
  144. data/lib/pry/commands/gem_install.rb +0 -32
  145. data/lib/pry/commands/gem_list.rb +0 -33
  146. data/lib/pry/commands/gem_open.rb +0 -29
  147. data/lib/pry/commands/gem_readme.rb +0 -25
  148. data/lib/pry/commands/gem_search.rb +0 -40
  149. data/lib/pry/commands/gem_stats.rb +0 -83
  150. data/lib/pry/commands/gist.rb +0 -102
  151. data/lib/pry/commands/install_command.rb +0 -54
  152. data/lib/pry/config/behavior.rb +0 -255
  153. data/lib/pry/config/convenience.rb +0 -28
  154. data/lib/pry/config/default.rb +0 -159
  155. data/lib/pry/config/memoization.rb +0 -48
  156. data/lib/pry/platform.rb +0 -91
  157. data/lib/pry/rubygem.rb +0 -84
  158. data/lib/pry/terminal.rb +0 -91
@@ -1,194 +1,189 @@
1
- class Pry::Slop
2
- class Commands
3
- include Enumerable
4
-
5
- attr_reader :config, :commands, :arguments
6
- attr_writer :banner
7
-
8
- # Create a new instance of Slop::Commands and optionally build
9
- # Slop instances via a block. Any configuration options used in
10
- # this method will be the default configuration options sent to
11
- # each Slop object created.
12
- #
13
- # config - An optional configuration Hash.
14
- # block - Optional block used to define commands.
15
- #
16
- # Examples:
17
- #
18
- # commands = Slop::Commands.new do
19
- # on :new do
20
- # on '-o', '--outdir=', 'The output directory'
21
- # on '-v', '--verbose', 'Enable verbose mode'
22
- # end
23
- #
24
- # on :generate do
25
- # on '--assets', 'Generate assets', :default => true
26
- # end
27
- #
28
- # global do
29
- # on '-D', '--debug', 'Enable debug mode', :default => false
30
- # end
31
- # end
32
- #
33
- # commands[:new].class #=> Slop
34
- # commands.parse
35
- #
36
- def initialize(config = {}, &block)
37
- @config = config
38
- @commands = {}
39
- @banner = nil
40
- @triggered_command = nil
41
-
42
- warn "[DEPRECATED] Slop::Commands is deprecated and will be removed in "\
43
- "Slop version 4. Check out http://injekt.github.com/slop/#commands for "\
44
- "a new implementation of commands."
45
-
46
- if block_given?
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Slop
5
+ class Commands
6
+ include Enumerable
7
+
8
+ attr_reader :config, :commands, :arguments
9
+ attr_writer :banner
10
+
11
+ # Create a new instance of Slop::Commands and optionally build
12
+ # Slop instances via a block. Any configuration options used in
13
+ # this method will be the default configuration options sent to
14
+ # each Slop object created.
15
+ #
16
+ # config - An optional configuration Hash.
17
+ # block - Optional block used to define commands.
18
+ #
19
+ # Examples:
20
+ #
21
+ # commands = Slop::Commands.new do
22
+ # on :new do
23
+ # on '-o', '--outdir=', 'The output directory'
24
+ # on '-v', '--verbose', 'Enable verbose mode'
25
+ # end
26
+ #
27
+ # on :generate do
28
+ # on '--assets', 'Generate assets', :default => true
29
+ # end
30
+ #
31
+ # global do
32
+ # on '-D', '--debug', 'Enable debug mode', :default => false
33
+ # end
34
+ # end
35
+ #
36
+ # commands[:new].class #=> Slop
37
+ # commands.parse
38
+ #
39
+ def initialize(config = {}, &block)
40
+ @config = config
41
+ @commands = {}
42
+ @banner = nil
43
+ @triggered_command = nil
44
+
45
+ warn "[DEPRECATED] Slop::Commands is deprecated and will be removed in "\
46
+ "Slop version 4. Check out http://injekt.github.com/slop/#commands for "\
47
+ "a new implementation of commands."
48
+
49
+ return unless block_given?
50
+
47
51
  block.arity == 1 ? yield(self) : instance_eval(&block)
48
52
  end
49
- end
50
53
 
51
- # Optionally set the banner for this command help output.
52
- #
53
- # banner - The String text to set the banner.
54
- #
55
- # Returns the String banner if one is set.
56
- def banner(banner = nil)
57
- @banner = banner if banner
58
- @banner
59
- end
54
+ # Optionally set the banner for this command help output.
55
+ #
56
+ # banner - The String text to set the banner.
57
+ #
58
+ # Returns the String banner if one is set.
59
+ def banner(banner = nil)
60
+ @banner = banner if banner
61
+ @banner
62
+ end
60
63
 
61
- # Add a Slop instance for a specific command.
62
- #
63
- # command - A String or Symbol key used to identify this command.
64
- # config - A Hash of configuration options to pass to Slop.
65
- # block - An optional block used to pass options to Slop.
66
- #
67
- # Returns the newly created Slop instance mapped to command.
68
- def on(command, config = {}, &block)
69
- commands[command.to_s] = Slop.new(@config.merge(config), &block)
70
- end
64
+ # Add a Slop instance for a specific command.
65
+ #
66
+ # command - A String or Symbol key used to identify this command.
67
+ # config - A Hash of configuration options to pass to Slop.
68
+ # block - An optional block used to pass options to Slop.
69
+ #
70
+ # Returns the newly created Slop instance mapped to command.
71
+ def on(command, config = {}, &block)
72
+ commands[command.to_s] = Slop.new(@config.merge(config), &block)
73
+ end
71
74
 
72
- # Add a Slop instance used when no other commands exist.
73
- #
74
- # config - A Hash of configuration options to pass to Slop.
75
- # block - An optional block used to pass options to Slop.
76
- #
77
- # Returns the newly created Slop instance mapped to default.
78
- def default(config = {}, &block)
79
- on('default', config, &block)
80
- end
75
+ # Add a Slop instance used when no other commands exist.
76
+ #
77
+ # config - A Hash of configuration options to pass to Slop.
78
+ # block - An optional block used to pass options to Slop.
79
+ #
80
+ # Returns the newly created Slop instance mapped to default.
81
+ def default(config = {}, &block)
82
+ on('default', config, &block)
83
+ end
81
84
 
82
- # Add a global Slop instance.
83
- #
84
- # config - A Hash of configuration options to pass to Slop.
85
- # block - An optional block used to pass options to Slop.
86
- #
87
- # Returns the newly created Slop instance mapped to global.
88
- def global(config = {}, &block)
89
- on('global', config, &block)
90
- end
85
+ # Add a global Slop instance.
86
+ #
87
+ # config - A Hash of configuration options to pass to Slop.
88
+ # block - An optional block used to pass options to Slop.
89
+ #
90
+ # Returns the newly created Slop instance mapped to global.
91
+ def global(config = {}, &block)
92
+ on('global', config, &block)
93
+ end
91
94
 
92
- # Fetch the instance of Slop tied to a command.
93
- #
94
- # key - The String or Symbol key used to locate this command.
95
- #
96
- # Returns the Slop instance if this key is found, nil otherwise.
97
- def [](key)
98
- commands[key.to_s]
99
- end
100
- alias get []
101
-
102
- # Check for a command presence.
103
- #
104
- # Examples:
105
- #
106
- # cmds.parse %w( foo )
107
- # cmds.present?(:foo) #=> true
108
- # cmds.present?(:bar) #=> false
109
- #
110
- # Returns true if the given key is present in the parsed arguments.
111
- def present?(key)
112
- key.to_s == @triggered_command
113
- end
95
+ # Fetch the instance of Slop tied to a command.
96
+ #
97
+ # key - The String or Symbol key used to locate this command.
98
+ #
99
+ # Returns the Slop instance if this key is found, nil otherwise.
100
+ def [](key)
101
+ commands[key.to_s]
102
+ end
103
+ alias get []
104
+
105
+ # Check for a command presence.
106
+ #
107
+ # Examples:
108
+ #
109
+ # cmds.parse %w( foo )
110
+ # cmds.present?(:foo) #=> true
111
+ # cmds.present?(:bar) #=> false
112
+ #
113
+ # Returns true if the given key is present in the parsed arguments.
114
+ def present?(key)
115
+ key.to_s == @triggered_command
116
+ end
114
117
 
115
- # Enumerable interface.
116
- def each(&block)
117
- @commands.each(&block)
118
- end
118
+ # Enumerable interface.
119
+ def each(&block)
120
+ @commands.each(&block)
121
+ end
119
122
 
120
- # Parse a list of items.
121
- #
122
- # items - The Array of items to parse.
123
- #
124
- # Returns the original Array of items.
125
- def parse(items = ARGV)
126
- parse! items.dup
127
- items
128
- end
123
+ # Parse a list of items.
124
+ #
125
+ # items - The Array of items to parse.
126
+ #
127
+ # Returns the original Array of items.
128
+ def parse(items = ARGV)
129
+ parse! items.dup
130
+ items
131
+ end
129
132
 
130
- # Parse a list of items, removing any options or option arguments found.
131
- #
132
- # items - The Array of items to parse.
133
- #
134
- # Returns the original Array of items with options removed.
135
- def parse!(items = ARGV)
136
- if (opts = commands[items[0].to_s])
137
- @triggered_command = items.shift
138
- execute_arguments! items
139
- opts.parse! items
140
- execute_global_opts! items
141
- else
142
- if (opts = commands['default'])
133
+ # Parse a list of items, removing any options or option arguments found.
134
+ #
135
+ # items - The Array of items to parse.
136
+ #
137
+ # Returns the original Array of items with options removed.
138
+ def parse!(items = ARGV)
139
+ if (opts = commands[items[0].to_s])
140
+ @triggered_command = items.shift
141
+ execute_arguments! items
142
+ opts.parse! items
143
+ elsif (opts = commands['default'])
143
144
  opts.parse! items
144
- else
145
- if config[:strict] && items[0]
146
- raise InvalidCommandError, "Unknown command `#{items[0]}`"
147
- end
145
+ elsif config[:strict] && items[0]
146
+ raise InvalidCommandError, "Unknown command `#{items[0]}`"
148
147
  end
149
148
  execute_global_opts! items
149
+ items
150
150
  end
151
- items
152
- end
153
151
 
154
- # Returns a nested Hash with Slop options and values. See Slop#to_hash.
155
- def to_hash
156
- Hash[commands.map { |k, v| [k.to_sym, v.to_hash] }]
157
- end
152
+ # Returns a nested Hash with Slop options and values. See Slop#to_hash.
153
+ def to_hash
154
+ Hash[commands.map { |k, v| [k.to_sym, v.to_hash] }]
155
+ end
158
156
 
159
- # Returns the help String.
160
- def to_s
161
- defaults = commands.delete('default')
162
- globals = commands.delete('global')
163
- helps = commands.reject { |_, v| v.options.none? }
164
- if globals && globals.options.any?
165
- helps.merge!('Global options' => globals.to_s)
157
+ # Returns the help String.
158
+ def to_s
159
+ defaults = commands.delete('default')
160
+ globals = commands.delete('global')
161
+ helps = commands.reject { |_, v| v.options.none? }
162
+ helps['Global options'] = globals.to_s if globals && globals.options.any?
163
+ helps['Other options'] = defaults.to_s if defaults && defaults.options.any?
164
+ banner = @banner ? "#{@banner}\n" : ""
165
+ banner + helps.map { |key, opts| " #{key}\n#{opts}" }.join("\n\n")
166
166
  end
167
- if defaults && defaults.options.any?
168
- helps.merge!('Other options' => defaults.to_s)
167
+ alias help to_s
168
+
169
+ # Returns the inspection String.
170
+ def inspect
171
+ "#<Slop::Commands #{config.inspect} #{commands.values.map(&:inspect)}>"
169
172
  end
170
- banner = @banner ? "#{@banner}\n" : ""
171
- banner + helps.map { |key, opts| " #{key}\n#{opts}" }.join("\n\n")
172
- end
173
- alias help to_s
174
173
 
175
- # Returns the inspection String.
176
- def inspect
177
- "#<Slop::Commands #{config.inspect} #{commands.values.map(&:inspect)}>"
178
- end
174
+ private
179
175
 
180
- private
176
+ # Returns nothing.
177
+ def execute_arguments!(items)
178
+ @arguments = items.take_while { |arg| !arg.start_with?('-') }
179
+ items.shift @arguments.size
180
+ end
181
181
 
182
- # Returns nothing.
183
- def execute_arguments!(items)
184
- @arguments = items.take_while { |arg| !arg.start_with?('-') }
185
- items.shift @arguments.size
186
- end
182
+ # Returns nothing.
183
+ def execute_global_opts!(items)
184
+ return unless (global_opts = commands['global'])
187
185
 
188
- # Returns nothing.
189
- def execute_global_opts!(items)
190
- if (global_opts = commands['global'])
191
- global_opts.parse! items
186
+ global_opts.parse!(items)
192
187
  end
193
188
  end
194
189
  end
@@ -1,203 +1,207 @@
1
- class Pry::Slop
2
- class Option
3
- # The default Hash of configuration options this class uses.
4
- DEFAULT_OPTIONS = {
5
- argument: false,
6
- optional_argument: false,
7
- tail: false,
8
- default: nil,
9
- callback: nil,
10
- delimiter: ',',
11
- limit: 0,
12
- match: nil,
13
- optional: true,
14
- required: false,
15
- as: String,
16
- autocreated: false
17
- }
18
-
19
- attr_reader :short, :long, :description, :config, :types
20
- attr_accessor :count, :argument_in_value
21
-
22
- # Incapsulate internal option information, mainly used to store
23
- # option specific configuration data, most of the meat of this
24
- # class is found in the #value method.
25
- #
26
- # slop - The instance of Slop tied to this Option.
27
- # short - The String or Symbol short flag.
28
- # long - The String or Symbol long flag.
29
- # description - The String description text.
30
- # config - A Hash of configuration options.
31
- # block - An optional block used as a callback.
32
- def initialize(slop, short, long, description, config = {}, &block)
33
- @slop = slop
34
- @short = short
35
- @long = long
36
- @description = description
37
- @config = DEFAULT_OPTIONS.merge(config)
38
- @count = 0
39
- @callback = block_given? ? block : config[:callback]
40
- @value = nil
41
-
42
- @types = {
43
- string: proc { |v| v.to_s },
44
- symbol: proc { |v| v.to_sym },
45
- integer: proc { |v| value_to_integer(v) },
46
- float: proc { |v| value_to_float(v) },
47
- range: proc { |v| value_to_range(v) },
48
- count: proc { |v| @count }
49
- }
50
-
51
- if long && long.size > @slop.config[:longest_flag]
52
- @slop.config[:longest_flag] = long.size
53
- end
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Slop
5
+ class Option
6
+ # The default Hash of configuration options this class uses.
7
+ DEFAULT_OPTIONS = {
8
+ argument: false,
9
+ optional_argument: false,
10
+ tail: false,
11
+ default: nil,
12
+ callback: nil,
13
+ delimiter: ',',
14
+ limit: 0,
15
+ match: nil,
16
+ optional: true,
17
+ required: false,
18
+ as: String,
19
+ autocreated: false
20
+ }.freeze
21
+
22
+ attr_reader :short, :long, :description, :config, :types
23
+ attr_accessor :count, :argument_in_value
24
+
25
+ # Incapsulate internal option information, mainly used to store
26
+ # option specific configuration data, most of the meat of this
27
+ # class is found in the #value method.
28
+ #
29
+ # slop - The instance of Slop tied to this Option.
30
+ # short - The String or Symbol short flag.
31
+ # long - The String or Symbol long flag.
32
+ # description - The String description text.
33
+ # config - A Hash of configuration options.
34
+ # block - An optional block used as a callback.
35
+ def initialize(slop, short, long, description, config = {}, &block)
36
+ @slop = slop
37
+ @short = short
38
+ @long = long
39
+ @description = description
40
+ @config = DEFAULT_OPTIONS.merge(config)
41
+ @count = 0
42
+ @callback = block_given? ? block : config[:callback]
43
+ @value = nil
44
+
45
+ @types = {
46
+ string: proc { |v| v.to_s },
47
+ symbol: proc { |v| v.to_sym },
48
+ integer: proc { |v| value_to_integer(v) },
49
+ float: proc { |v| value_to_float(v) },
50
+ range: proc { |v| value_to_range(v) },
51
+ count: proc { @count }
52
+ }
53
+
54
+ if long && long.size > @slop.config[:longest_flag]
55
+ @slop.config[:longest_flag] = long.size
56
+ end
54
57
 
55
- @config.each_key do |key|
56
- predicate = :"#{key}?"
57
- unless self.class.method_defined? predicate
58
- self.class.__send__(:define_method, predicate) { !!@config[key] }
58
+ @config.each_key do |key|
59
+ predicate = :"#{key}?"
60
+ unless self.class.method_defined?(predicate)
61
+ self.class.__send__(:define_method, predicate) { !@config.key?(key) }
62
+ end
59
63
  end
60
64
  end
61
- end
62
65
 
63
- # Returns true if this option expects an argument.
64
- def expects_argument?
65
- config[:argument] && config[:argument] != :optional
66
- end
66
+ # Returns true if this option expects an argument.
67
+ def expects_argument?
68
+ config[:argument] && config[:argument] != :optional
69
+ end
67
70
 
68
- # Returns true if this option accepts an optional argument.
69
- def accepts_optional_argument?
70
- config[:optional_argument] || config[:argument] == :optional
71
- end
71
+ # Returns true if this option accepts an optional argument.
72
+ def accepts_optional_argument?
73
+ config[:optional_argument] || config[:argument] == :optional
74
+ end
72
75
 
73
- # Returns the String flag of this option. Preferring the long flag.
74
- def key
75
- long || short
76
- end
76
+ # Returns the String flag of this option. Preferring the long flag.
77
+ def key
78
+ long || short
79
+ end
77
80
 
78
- # Call this options callback if one exists, and it responds to call().
79
- #
80
- # Returns nothing.
81
- def call(*objects)
82
- @callback.call(*objects) if @callback.respond_to?(:call)
83
- end
81
+ # Call this options callback if one exists, and it responds to call().
82
+ #
83
+ # Returns nothing.
84
+ def call(*objects)
85
+ @callback.call(*objects) if @callback.respond_to?(:call)
86
+ end
84
87
 
85
- # Set the new argument value for this option.
86
- #
87
- # We use this setter method to handle concatenating lists. That is,
88
- # when an array type is specified and used more than once, values from
89
- # both options will be grouped together and flattened into a single array.
90
- def value=(new_value)
91
- if config[:as].to_s.downcase == 'array'
92
- @value ||= []
93
-
94
- if new_value.respond_to?(:split)
95
- @value.concat new_value.split(config[:delimiter], config[:limit])
88
+ # Set the new argument value for this option.
89
+ #
90
+ # We use this setter method to handle concatenating lists. That is,
91
+ # when an array type is specified and used more than once, values from
92
+ # both options will be grouped together and flattened into a single array.
93
+ def value=(new_value)
94
+ if config[:as].to_s.casecmp('array') == 0
95
+ @value ||= []
96
+
97
+ if new_value.respond_to?(:split)
98
+ @value.concat new_value.split(config[:delimiter], config[:limit])
99
+ end
100
+ else
101
+ @value = new_value
96
102
  end
97
- else
98
- @value = new_value
99
103
  end
100
- end
101
104
 
102
- # Fetch the argument value for this option.
103
- #
104
- # Returns the Object once any type conversions have taken place.
105
- def value
106
- value = @value.nil? ? config[:default] : @value
105
+ # Fetch the argument value for this option.
106
+ #
107
+ # Returns the Object once any type conversions have taken place.
108
+ def value
109
+ value = @value.nil? ? config[:default] : @value
107
110
 
108
- if [true, false, nil].include?(value) && config[:as].to_s != 'count'
109
- return value
110
- end
111
+ return value if [true, false, nil].include?(value) && config[:as].to_s != 'count'
111
112
 
112
- type = config[:as]
113
- if type.respond_to?(:call)
114
- type.call(value)
115
- else
116
- if (callable = types[type.to_s.downcase.to_sym])
113
+ type = config[:as]
114
+ if type.respond_to?(:call)
115
+ type.call(value)
116
+ elsif (callable = types[type.to_s.downcase.to_sym])
117
117
  callable.call(value)
118
118
  else
119
119
  value
120
120
  end
121
121
  end
122
- end
123
122
 
124
- # Returns the help String for this option.
125
- def to_s
126
- return config[:help] if config[:help].respond_to?(:to_str)
123
+ # Returns the help String for this option.
124
+ def to_s
125
+ return config[:help] if config[:help].respond_to?(:to_str)
127
126
 
128
- out = " #{short ? "-#{short}, " : ' ' * 4}"
127
+ out = " #{short ? "-#{short}, " : ' ' * 4}"
129
128
 
130
- if long
131
- out << "--#{long}"
132
- size = long.size
133
- diff = @slop.config[:longest_flag] - size
134
- out << (' ' * (diff + 6))
135
- else
136
- out << (' ' * (@slop.config[:longest_flag] + 8))
129
+ if long
130
+ out += "--#{long}"
131
+ size = long.size
132
+ diff = @slop.config[:longest_flag] - size
133
+ out += (' ' * (diff + 6))
134
+ else
135
+ out += (' ' * (@slop.config[:longest_flag] + 8))
136
+ end
137
+
138
+ "#{out}#{description}"
137
139
  end
140
+ alias help to_s
138
141
 
139
- "#{out}#{description}"
140
- end
141
- alias help to_s
142
+ # Returns the String inspection text.
143
+ def inspect
144
+ "#<Slop::Option [-#{short} | --#{long}" \
145
+ "#{'=' if expects_argument?}#{'=?' if accepts_optional_argument?}]" \
146
+ " (#{description}) #{config.inspect}"
147
+ end
142
148
 
143
- # Returns the String inspection text.
144
- def inspect
145
- "#<Slop::Option [-#{short} | --#{long}" +
146
- "#{'=' if expects_argument?}#{'=?' if accepts_optional_argument?}]" +
147
- " (#{description}) #{config.inspect}"
148
- end
149
+ private
149
150
 
150
- private
151
-
152
- # Convert an object to an Integer if possible.
153
- #
154
- # value - The Object we want to convert to an integer.
155
- #
156
- # Returns the Integer value if possible to convert, else a zero.
157
- def value_to_integer(value)
158
- if @slop.strict?
159
- begin
160
- Integer(value.to_s, 10)
161
- rescue ArgumentError
162
- raise InvalidArgumentError, "#{value} could not be coerced into Integer"
151
+ # Convert an object to an Integer if possible.
152
+ #
153
+ # value - The Object we want to convert to an integer.
154
+ #
155
+ # Returns the Integer value if possible to convert, else a zero.
156
+ def value_to_integer(value)
157
+ if @slop.strict?
158
+ begin
159
+ Integer(value.to_s, 10)
160
+ rescue ArgumentError
161
+ raise InvalidArgumentError, "#{value} could not be coerced into Integer"
162
+ end
163
+ else
164
+ value.to_s.to_i
163
165
  end
164
- else
165
- value.to_s.to_i
166
166
  end
167
- end
168
167
 
169
- # Convert an object to a Float if possible.
170
- #
171
- # value - The Object we want to convert to a float.
172
- #
173
- # Returns the Float value if possible to convert, else a zero.
174
- def value_to_float(value)
175
- if @slop.strict?
176
- begin
177
- Float(value.to_s)
178
- rescue ArgumentError
179
- raise InvalidArgumentError, "#{value} could not be coerced into Float"
168
+ # Convert an object to a Float if possible.
169
+ #
170
+ # value - The Object we want to convert to a float.
171
+ #
172
+ # Returns the Float value if possible to convert, else a zero.
173
+ def value_to_float(value)
174
+ if @slop.strict?
175
+ begin
176
+ Float(value.to_s)
177
+ rescue ArgumentError
178
+ raise InvalidArgumentError, "#{value} could not be coerced into Float"
179
+ end
180
+ else
181
+ value.to_s.to_f
180
182
  end
181
- else
182
- value.to_s.to_f
183
183
  end
184
- end
185
184
 
186
- # Convert an object to a Range if possible.
187
- #
188
- # value - The Object we want to convert to a range.
189
- #
190
- # Returns the Range value if one could be found, else the original object.
191
- def value_to_range(value)
192
- case value.to_s
193
- when /\A(\-?\d+)\z/
194
- Range.new($1.to_i, $1.to_i)
195
- when /\A(-?\d+?)(\.\.\.?|-|,)(-?\d+)\z/
196
- Range.new($1.to_i, $3.to_i, $2 == '...')
197
- else
198
- if @slop.strict?
199
- raise InvalidArgumentError, "#{value} could not be coerced into Range"
185
+ # Convert an object to a Range if possible.
186
+ #
187
+ # value - The Object we want to convert to a range.
188
+ #
189
+ # Returns the Range value if one could be found, else the original object.
190
+ def value_to_range(value)
191
+ case value.to_s
192
+ when /\A(\-?\d+)\z/
193
+ Range.new(Regexp.last_match(1).to_i, Regexp.last_match(1).to_i)
194
+ when /\A(-?\d+?)(\.\.\.?|-|,)(-?\d+)\z/
195
+ Range.new(
196
+ Regexp.last_match(1).to_i,
197
+ Regexp.last_match(3).to_i,
198
+ Regexp.last_match(2) == '...'
199
+ )
200
200
  else
201
+ if @slop.strict?
202
+ raise InvalidArgumentError, "#{value} could not be coerced into Range"
203
+ end
204
+
201
205
  value
202
206
  end
203
207
  end