tty-prompt 0.11.0 → 0.12.0

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/README.md +66 -7
  4. data/examples/key_events.rb +11 -0
  5. data/examples/keypress.rb +3 -5
  6. data/examples/multiline.rb +9 -0
  7. data/examples/pause.rb +7 -0
  8. data/lib/tty/prompt.rb +82 -44
  9. data/lib/tty/prompt/confirm_question.rb +20 -36
  10. data/lib/tty/prompt/enum_list.rb +32 -23
  11. data/lib/tty/prompt/expander.rb +35 -31
  12. data/lib/tty/prompt/keypress.rb +91 -0
  13. data/lib/tty/prompt/list.rb +38 -23
  14. data/lib/tty/prompt/mask_question.rb +4 -7
  15. data/lib/tty/prompt/multi_list.rb +3 -1
  16. data/lib/tty/prompt/multiline.rb +71 -0
  17. data/lib/tty/prompt/question.rb +33 -35
  18. data/lib/tty/prompt/reader.rb +154 -38
  19. data/lib/tty/prompt/reader/codes.rb +4 -4
  20. data/lib/tty/prompt/reader/console.rb +1 -1
  21. data/lib/tty/prompt/reader/history.rb +145 -0
  22. data/lib/tty/prompt/reader/key_event.rb +4 -0
  23. data/lib/tty/prompt/reader/line.rb +162 -0
  24. data/lib/tty/prompt/reader/mode.rb +2 -2
  25. data/lib/tty/prompt/reader/win_console.rb +5 -1
  26. data/lib/tty/prompt/slider.rb +18 -12
  27. data/lib/tty/prompt/timeout.rb +48 -0
  28. data/lib/tty/prompt/version.rb +1 -1
  29. data/spec/unit/ask_spec.rb +15 -0
  30. data/spec/unit/converters/convert_bool_spec.rb +1 -0
  31. data/spec/unit/keypress_spec.rb +35 -6
  32. data/spec/unit/multi_select_spec.rb +18 -0
  33. data/spec/unit/multiline_spec.rb +67 -9
  34. data/spec/unit/question/default_spec.rb +1 -0
  35. data/spec/unit/question/echo_spec.rb +8 -0
  36. data/spec/unit/question/in_spec.rb +13 -0
  37. data/spec/unit/question/required_spec.rb +31 -2
  38. data/spec/unit/question/validate_spec.rb +39 -9
  39. data/spec/unit/reader/history_spec.rb +172 -0
  40. data/spec/unit/reader/key_event_spec.rb +12 -8
  41. data/spec/unit/reader/line_spec.rb +110 -0
  42. data/spec/unit/reader/publish_keypress_event_spec.rb +11 -0
  43. data/spec/unit/reader/read_line_spec.rb +32 -2
  44. data/spec/unit/reader/read_multiline_spec.rb +21 -7
  45. data/spec/unit/select_spec.rb +40 -1
  46. data/spec/unit/yes_no_spec.rb +48 -4
  47. metadata +14 -3
  48. data/lib/tty/prompt/history.rb +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4ff94c2773632a84c5e652c8c725cdc576718ae6
4
- data.tar.gz: 382b630ad1f975325744210cb7a308bfc09175e2
3
+ metadata.gz: 7c73bc3ac5978ca2ec1610fee367e6e04e66c0ec
4
+ data.tar.gz: 3350a73010eb30efd4494799ff5a6e8437115a42
5
5
  SHA512:
6
- metadata.gz: ed722a06def652f9cb1e02fa627fe28ebfdfa0a8bdfa7a36e426b8976d4c0eab287f1e50f2800f2b7c87a185d1b4325d7628409991f6ba9061029976909c2805
7
- data.tar.gz: 5bad4344ba8e132eaf35409329ab8583aa52f2a94a296b5b23eb13cb11c3436e71601c7bd9351ecf17d70b1851d910b2600e4ea8cfea81e08d3de507edbfa43f
6
+ metadata.gz: cd4716769f48d957e8ef5f4167a231d042126ab565267697b3541cd150629c669079275c1cdf66b7d3bba60b02d0b800458d3b84d1f0d0fa26c3c7cce202b709
7
+ data.tar.gz: 003c09c9afe7d9f3e3b6014bc5352150f49a1609827c637342605f34fcbbac59f0a913b6d20f68cad8b698387b720c00f3025ab3a1fa30984b226adaada07f1f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.12.0] - 2017-03-19
4
+
5
+ ### Added
6
+ * Add Multiline question type
7
+ * Add Keypress question type
8
+ * Add Reader::History for storing buffered lines
9
+ * Add Reader::Line for line abstraction
10
+
11
+ ### Changed
12
+ * Remove :read option from Question
13
+ * Chnage Reader#read_line to handle raw mode for processing special
14
+ characters such as Ctrl+x, navigate through history buffer
15
+ using up/down arrows, allow editing current line by moving left/right
16
+ with arrow keys and inserting content
17
+ * Change Reader#read_multiline to gather multi line input correctly,
18
+ skip empty lines and terminate when Ctrl+d and Ctrl+z are pressed
19
+ * Change Reader::Mode to check if tty is available by Matt Martyn (@MMartyn)
20
+ * Change #keypress prompt to correctly refresh line and accept :keys & :timeout options
21
+
22
+ ### Fixed
23
+ * Fix issue with #select, #multi_selct, #enum_select when choices are
24
+ provided as hash object together with prompt options.
25
+ * Fix issue with default parameter for yes?/no? prompt by Carlos Fonseca (@carlosefonseca)
26
+ * Fix List#help to allow setting help text through DSL
27
+
3
28
  ## [v0.11.0] - 2017-02-26
4
29
 
5
30
  ### Added
data/README.md CHANGED
@@ -56,6 +56,7 @@ Or install it yourself as:
56
56
  * [2.1.7 required](#217-required)
57
57
  * [2.1.8 validate](#218-validate)
58
58
  * [2.2 keypress](#22-keypress)
59
+ * [2.2.1 timeout](#221-timeout)
59
60
  * [2.3 multiline](#23-multiline)
60
61
  * [2.4 mask](#24-mask)
61
62
  * [2.5 yes?/no?](#25-yesno)
@@ -79,6 +80,7 @@ Or install it yourself as:
79
80
  * [3.3 help_color](#33-help_color)
80
81
  * [3.4 interrupt](#34-interrupt)
81
82
  * [3.5 prefix](#35-prefix)
83
+ * [3.6 trakc_history](#36-track_history)
82
84
 
83
85
  ## 1. Usage
84
86
 
@@ -349,21 +351,61 @@ prompt.ask('What is your email?') { |q| q.validate :email }
349
351
 
350
352
  ### 2.2. keypress
351
353
 
352
- In order to ask question with a single character or keypress answer use `keypress`:
354
+ In order to ask question that awaits a single character answer use `keypress` prompt like so:
353
355
 
354
356
  ```ruby
355
- prompt.keypress("Which one do you prefer a, b, c or d ?")
357
+ prompt.keypress("Press key ?")
358
+ # Press key?
359
+ # => a
360
+ ```
361
+
362
+ By default any key is accepted but you can limit keys by using `:keys` option. Any key event names such as `:space` or `:ctrl_k` are valid:
363
+
364
+ ```ruby
365
+ prompt.keypress("Press space or enter to continue, keys: [:space, :return])
366
+ ```
367
+
368
+ #### 2.2.1 timeout
369
+
370
+ Timeout can be set using `:timeout` option to expire prompt and allow the script to continue automatically:
371
+
372
+ ```ruby
373
+ prompt.keypress("Press any key to continue, resumes automatically in 3 seconds ...", timeout: 3)
374
+ ```
375
+
376
+ In addition the `keypress` recognises `:countdown` token when inserted inside the question. It will automatically countdown the time in seconds:
377
+
378
+ ```ruby
379
+ prompt.keypress("Press any key to continue, resumes automatically in :countdown ...", timeout: 3)
356
380
  ```
357
381
 
358
382
  ### 2.3 multiline
359
383
 
360
- Asking for multiline input can be done with `multiline` method.
384
+ Asking for multiline input can be done with `multiline` method. The reading of input will terminate when `Ctrl+d` or `Ctrl+z` is pressed. Empty lines will not be included in the returned array.
361
385
 
362
386
  ```ruby
363
- prompt.multiline("Provide description?")
387
+ prompt.multiline("Description?")
388
+ # Description? (Press CTRL-D or CTRL-Z to finish)
389
+ # I know not all that may be coming,
390
+ # but be it what it will,
391
+ # I'll go to it laughing.
392
+ # => ["I know not all that may be coming,\n", "but be it what it will,\n", "I'll go to it laughing.\n"]
364
393
  ```
365
394
 
366
- The reading of input will terminate when empty line is submitted.
395
+ The `multiline` uses similar options to those supported by `ask` prompt. For example, to provide default description:
396
+
397
+ ```ruby
398
+ prompt.multiline("Description?", default: 'A super sweet prompt.')
399
+ ```
400
+
401
+ or using DSL:
402
+
403
+ ```ruby
404
+ prompt.multiline("Description?") do |q|
405
+ q.default 'A super sweet prompt.'
406
+ q.help 'Press thy ctrl+d to end'
407
+ end
408
+ ```
367
409
 
368
410
  ### 2.4 mask
369
411
 
@@ -377,8 +419,9 @@ prompt.mask('What is your secret?')
377
419
  The masking character can be changed by passing `:mask` option:
378
420
 
379
421
  ```ruby
380
- prompt.mask('What is your secret?', mask: '\u2665')
381
- # => What is your secret? ♥♥♥♥♥
422
+ heart = prompt.decorate(' ', :magenta)
423
+ prompt.mask('What is your secret?', mask: heart)
424
+ # => What is your secret? ❤ ❤ ❤ ❤ ❤
382
425
  ```
383
426
 
384
427
  If you don't wish to show any output use `:echo` option like so:
@@ -387,6 +430,14 @@ If you don't wish to show any output use `:echo` option like so:
387
430
  prompt.mask('What is your secret?', echo: false)
388
431
  ```
389
432
 
433
+ You can also provide validation for your mask to enforce for instance strong passwords:
434
+
435
+ ```ruby
436
+ prompt.mask('What is your secret?', mask: heart) do |q|
437
+ q.validate(/[a-z\ ]{5,15}/)
438
+ end
439
+ ```
440
+
390
441
  ### 2.5 yes?/no?
391
442
 
392
443
  In order to display a query asking for boolean input from user use `yes?` like so:
@@ -1058,6 +1109,14 @@ You can prefix each question asked using the `:prefix` option. This option can b
1058
1109
  prompt = TTY::Prompt.new(prefix: '[?] ')
1059
1110
  ```
1060
1111
 
1112
+ ### 3.6 track_history
1113
+
1114
+ The prompts that accept line input such as `multiline` or `ask` provide history buffer that tracks all the lines entered during `TTY::Prompt.new` interactions. The history buffer provides previoius or next lines when user presses up/down arrows respectively. However, if you wish to disable this behaviour use `:track_history` option like so:
1115
+
1116
+ ```ruby
1117
+ prompt = TTY::Prompt.new(track_history: false)
1118
+ ```
1119
+
1061
1120
  ## Contributing
1062
1121
 
1063
1122
  1. Fork it ( https://github.com/piotrmurach/tty-prompt/fork )
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'tty-prompt'
4
+
5
+ prompt = TTY::Prompt::new(interrupt: :exit)
6
+
7
+ prompt.on(:keypress) do |event|
8
+ puts "name: #{event.key.name}, value: #{event.value.dump}"
9
+ end
10
+
11
+ prompt.read_keypress
data/examples/keypress.rb CHANGED
@@ -2,10 +2,8 @@
2
2
 
3
3
  require 'tty-prompt'
4
4
 
5
- prompt = TTY::Prompt::new(interrupt: :exit)
5
+ prompt = TTY::Prompt::new
6
6
 
7
- prompt.on(:keypress) do |event|
8
- puts "name: #{event.key.name}, value: #{event.value.dump}"
9
- end
7
+ answer = prompt.keypress("Press any key to continue")
10
8
 
11
- prompt.read_keypress
9
+ puts "Answer: #{answer}"
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ require 'tty-prompt'
4
+
5
+ prompt = TTY::Prompt::new
6
+
7
+ answer = prompt.multiline("Description:")
8
+
9
+ puts "Answer: #{answer.inspect}"
data/examples/pause.rb ADDED
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ require 'tty-prompt'
4
+
5
+ prompt = TTY::Prompt::new
6
+
7
+ prompt.keypress("Press space or enter to continue, continuing automatically in :countdown ...", keys: [:space, :return], timeout: 3)
data/lib/tty/prompt.rb CHANGED
@@ -8,8 +8,10 @@ require_relative 'prompt/answers_collector'
8
8
  require_relative 'prompt/confirm_question'
9
9
  require_relative 'prompt/expander'
10
10
  require_relative 'prompt/enum_list'
11
+ require_relative 'prompt/keypress'
11
12
  require_relative 'prompt/list'
12
13
  require_relative 'prompt/multi_list'
14
+ require_relative 'prompt/multiline'
13
15
  require_relative 'prompt/mask_question'
14
16
  require_relative 'prompt/question'
15
17
  require_relative 'prompt/reader'
@@ -87,6 +89,28 @@ module TTY
87
89
 
88
90
  # Initialize a Prompt
89
91
  #
92
+ # @param [Hash] options
93
+ # @option options [IO] :input
94
+ # the input stream
95
+ # @option options [IO] :output
96
+ # the output stream
97
+ # @option options [Hash] :env
98
+ # the environment variables
99
+ # @option options [String] :prefix
100
+ # the prompt prefix, by default empty
101
+ # @option options [Boolean] :enable_color
102
+ # enable color support, true by default
103
+ # @option options [String] :active_color
104
+ # the color used for selected option
105
+ # @option options [String] :help_color
106
+ # the color used for help text
107
+ # @option options [String] :error_color
108
+ # the color used for displaying error messages
109
+ # @option options [Symbol] :interrupt
110
+ # handling of Ctrl+C key out of :signal, :exit, :noop
111
+ # @option options [Boolean] :track_history
112
+ # disable line history tracking, true by default
113
+ #
90
114
  # @api public
91
115
  def initialize(*args)
92
116
  options = Utils.extract_options!(args)
@@ -98,10 +122,29 @@ module TTY
98
122
  @active_color = options.fetch(:active_color) { :green }
99
123
  @help_color = options.fetch(:help_color) { :bright_black }
100
124
  @error_color = options.fetch(:error_color) { :red }
125
+ @interrupt = options.fetch(:interrupt) { :error }
126
+ @track_history = options.fetch(:track_history) { true }
101
127
 
102
128
  @cursor = TTY::Cursor
103
129
  @pastel = Pastel.new(@enabled_color.nil? ? {} : { enabled: @enabled_color })
104
- @reader = Reader.new(@input, @output, interrupt: options[:interrupt], env: @env)
130
+ @reader = Reader.new(@input, @output, interrupt: @interrupt,
131
+ track_history: @track_history, env: @env)
132
+ end
133
+
134
+ # Invoke a question type of prompt
135
+ #
136
+ # @example
137
+ # prompt = TTY::Prompt.new
138
+ # prompt.invoke_question(Question, "Your name? ")
139
+ #
140
+ # @return [String]
141
+ #
142
+ # @api public
143
+ def invoke_question(object, message, *args, &block)
144
+ options = Utils.extract_options!(args)
145
+ options[:messages] = self.class.messages
146
+ question = object.new(self, options)
147
+ question.(message, &block)
105
148
  end
106
149
 
107
150
  # Ask a question.
@@ -122,10 +165,7 @@ module TTY
122
165
  #
123
166
  # @api public
124
167
  def ask(message, *args, &block)
125
- options = Utils.extract_options!(args)
126
- options.merge!({messages: self.class.messages})
127
- question = Question.new(self, options)
128
- question.call(message, &block)
168
+ invoke_question(Question, message, *args, &block)
129
169
  end
130
170
 
131
171
  # Ask a question with a keypress answer
@@ -134,22 +174,47 @@ module TTY
134
174
  #
135
175
  # @api public
136
176
  def keypress(message, *args, &block)
137
- options = Utils.extract_options!(args)
138
- options.merge!(read: :keypress)
139
- args << options
140
- ask(message, *args, &block)
177
+ invoke_question(Keypress, message, *args, &block)
141
178
  end
142
179
 
143
180
  # Ask a question with a multiline answer
144
181
  #
145
- # @see @ask
182
+ # @example
183
+ # prompt.multiline('Description?')
184
+ #
185
+ # @return [Array[String]]
146
186
  #
147
187
  # @api public
148
188
  def multiline(message, *args, &block)
189
+ invoke_question(Multiline, message, *args, &block)
190
+ end
191
+
192
+ # Invoke a list type of prompt
193
+ #
194
+ # @example
195
+ # prompt = TTY::Prompt.new
196
+ # editors = %w(emacs nano vim)
197
+ # prompt.invoke_select(EnumList, "Select editor: ", editors)
198
+ #
199
+ # @return [String]
200
+ #
201
+ # @api public
202
+ def invoke_select(object, question, *args, &block)
149
203
  options = Utils.extract_options!(args)
150
- options.merge!(read: :multiline)
151
- args << options
152
- ask(message, *args, &block)
204
+ choices = if block
205
+ []
206
+ elsif args.empty?
207
+ possible = options.dup
208
+ options = {}
209
+ possible
210
+ elsif args.size == 1 && args[0].is_a?(Hash)
211
+ Utils.extract_options!(args)
212
+ else
213
+ args.flatten
214
+ end
215
+
216
+ list = object.new(self, options)
217
+ list.(question, choices, &block)
153
218
  end
154
219
 
155
220
  # Ask masked question
@@ -162,10 +227,7 @@ module TTY
162
227
  #
163
228
  # @api public
164
229
  def mask(message, *args, &block)
165
- options = Utils.extract_options!(args)
166
- options.merge!({messages: self.class.messages})
167
- question = MaskQuestion.new(self, options)
168
- question.call(message, &block)
230
+ invoke_question(MaskQuestion, message, *args, &block)
169
231
  end
170
232
 
171
233
  # Ask a question with a list of options
@@ -232,30 +294,6 @@ module TTY
232
294
  invoke_select(EnumList, question, *args, &block)
233
295
  end
234
296
 
235
- # Invoke a list type of prompt
236
- #
237
- # @example
238
- # prompt = TTY::Prompt.new
239
- # editors = %w(emacs nano vim)
240
- # prompt.invoke_select(EnumList, "Select editor: ", editors)
241
- #
242
- # @return [String]
243
- #
244
- # @api public
245
- def invoke_select(object, question, *args, &block)
246
- options = Utils.extract_options!(args)
247
- choices = if block
248
- []
249
- elsif args.empty?
250
- options
251
- else
252
- args.flatten
253
- end
254
-
255
- list = object.new(self, options)
256
- list.call(question, choices, &block)
257
- end
258
-
259
297
  # A shortcut method to ask the user positive question and return
260
298
  # true for 'yes' reply, false for 'no'.
261
299
  #
@@ -288,7 +326,7 @@ module TTY
288
326
  #
289
327
  # @api public
290
328
  def no?(message, *args, &block)
291
- defaults = { default: false, type: :no }
329
+ defaults = { default: false }
292
330
  options = Utils.extract_options!(args)
293
331
  options.merge!(defaults.reject { |k, _| options.key?(k) })
294
332
 
@@ -350,7 +388,7 @@ module TTY
350
388
  # @api public
351
389
  def say(message = '', options = {})
352
390
  message = message.to_s
353
- return unless message.length > 0
391
+ return if message.empty?
354
392
 
355
393
  statement = Statement.new(self, options)
356
394
  statement.call(message)
@@ -491,7 +529,7 @@ module TTY
491
529
  enabled_color: enabled_color,
492
530
  help_color: help_color
493
531
  }
494
- "#<#{self.class}: #{attributes.each { |name, val| "@#{name}=#{val}" } }"
532
+ "#<#{self.class}: #{attributes.each { |name, val| "@#{name}=#{val}" }}"
495
533
  end
496
534
  end # Prompt
497
535
  end # TTY
@@ -16,11 +16,9 @@ module TTY
16
16
  # @api public
17
17
  def initialize(prompt, options = {})
18
18
  super
19
-
20
19
  @suffix = options.fetch(:suffix) { UndefinedSetting }
21
20
  @positive = options.fetch(:positive) { UndefinedSetting }
22
21
  @negative = options.fetch(:negative) { UndefinedSetting }
23
- @type = options.fetch(:type) { :yes }
24
22
  end
25
23
 
26
24
  def positive?
@@ -38,21 +36,24 @@ module TTY
38
36
  # Set question suffix
39
37
  #
40
38
  # @api public
41
- def suffix(value)
39
+ def suffix(value = (not_set = true))
40
+ return @negative if not_set
42
41
  @suffix = value
43
42
  end
44
43
 
45
44
  # Set value for matching positive choice
46
45
  #
47
46
  # @api public
48
- def positive(value)
47
+ def positive(value = (not_set = true))
48
+ return @positive if not_set
49
49
  @positive = value
50
50
  end
51
51
 
52
52
  # Set value for matching negative choice
53
53
  #
54
54
  # @api public
55
- def negative(value)
55
+ def negative(value = (not_set = true))
56
+ return @negative if not_set
56
57
  @negative = value
57
58
  end
58
59
 
@@ -66,10 +67,11 @@ module TTY
66
67
 
67
68
  # Render confirmation question
68
69
  #
70
+ # @return [String]
71
+ #
69
72
  # @api private
70
73
  def render_question
71
74
  header = "#{@prefix}#{message} "
72
-
73
75
  if !@done
74
76
  header += @prompt.decorate("(#{@suffix})", @help_color) + ' '
75
77
  else
@@ -77,24 +79,17 @@ module TTY
77
79
  label = answer ? @positive : @negative
78
80
  header += @prompt.decorate(label, @active_color)
79
81
  end
80
- @prompt.print(header)
81
- @prompt.puts if @done
82
-
83
- header.lines.count + (@done ? 1 : 0)
82
+ header << "\n" if @done
83
+ header
84
84
  end
85
85
 
86
86
  protected
87
87
 
88
- # @api private
89
- def is?(type)
90
- @type == type
91
- end
92
-
93
88
  # @api private
94
89
  def setup_defaults
95
90
  return if suffix? && positive?
96
91
 
97
- if suffix? && !positive?
92
+ if suffix? && (!positive? || !negative?)
98
93
  parts = @suffix.split('/')
99
94
  @positive = parts[0]
100
95
  @negative = parts[1]
@@ -104,41 +99,30 @@ module TTY
104
99
  @convert = conversion
105
100
  else
106
101
  create_default_labels
107
- @convert = :bool
102
+ @convert = :bool
108
103
  end
109
104
  end
110
105
 
106
+ # @api private
111
107
  def create_default_labels
112
- if is?(:yes)
113
- @suffix = default? ? 'Y/n' : 'y/N'
114
- @positive = default? ? 'Yes' : 'yes'
115
- @negative = default? ? 'no' : 'No'
116
- else
117
- @suffix = default? ? 'y/N' : 'Y/n'
118
- @positive = default? ? 'Yes' : 'yes'
119
- @negative = default? ? 'No' : 'no'
120
- end
108
+ @suffix = default ? 'Y/n' : 'y/N'
109
+ @positive = default ? 'Yes' : 'yes'
110
+ @negative = default ? 'no' : 'No'
121
111
  end
122
112
 
123
113
  # @api private
124
114
  def create_suffix
125
115
  result = ''
126
- if is?(:yes)
127
- result << "#{default? ? @positive.capitalize : @positive.downcase}"
128
- result << '/'
129
- result << "#{default? ? @negative.downcase : @negative.capitalize}"
130
- else
131
- result << "#{default? ? @positive.downcase : @positive.capitalize}"
132
- result << '/'
133
- result << "#{default? ? @negative.capitalize : @negative.downcase}"
134
- end
116
+ result << "#{default ? positive.capitalize : positive.downcase}"
117
+ result << '/'
118
+ result << "#{default ? negative.downcase : negative.capitalize}"
135
119
  end
136
120
 
137
121
  # Create custom conversion
138
122
  #
139
123
  # @api private
140
124
  def conversion
141
- proc { |input| !input.match(/^#{@positive}|#{@positive[0]}$/i).nil? }
125
+ proc { |input| !input.match(/^#{positive}|#{positive[0]}$/i).nil? }
142
126
  end
143
127
  end # ConfirmQuestion
144
128
  end # Prompt