slop 2.3.1 → 2.4.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.
data/CHANGES.md CHANGED
@@ -1,3 +1,10 @@
1
+ 2.4.0 (2011-11-26)
2
+ ------------------
3
+
4
+ * Avoid `define_method` for checking an options presence (and caching it) #37
5
+ * Ensure the short option allows an appended `=` for accepting arguments
6
+ * Implement `respond_to?`
7
+
1
8
  2.3.1 (2011-11-11)
2
9
  ------------------
3
10
 
data/lib/slop.rb CHANGED
@@ -2,7 +2,7 @@ class Slop
2
2
  include Enumerable
3
3
 
4
4
  # @return [String] The current version string
5
- VERSION = '2.3.1'
5
+ VERSION = '2.4.0'
6
6
 
7
7
  # Slops standard Error class. All exception classes should
8
8
  # inherit from this class
@@ -98,8 +98,7 @@ class Slop
98
98
  self.forced = false
99
99
  self.count = 0
100
100
 
101
- @callback = blk if block_given?
102
- @callback ||= @options[:callback]
101
+ @callback = block_given? ? blk : @options[:callback]
103
102
 
104
103
  if long_flag && long_flag.size > @slop.longest_flag
105
104
  @slop.longest_flag = long_flag.size
@@ -114,7 +113,7 @@ class Slop
114
113
 
115
114
  # @return [Boolean] true if this option accepts an optional argument
116
115
  def accepts_optional_argument?
117
- @options[:optional]
116
+ @options[:optional] || @options[:optional_argument]
118
117
  end
119
118
 
120
119
  # @return [String] either the long or short flag for this option
@@ -183,8 +182,9 @@ class Slop
183
182
  # @return [Boolean] true if this options `:unless` argument exists
184
183
  # inside *items*
185
184
  def omit_exec?(items)
186
- string = @options[:unless].to_s.sub(/\A--?/, '')
187
- items.any? { |i| i.to_s.sub(/\A--?/, '') == string }
185
+ items.any? do |item|
186
+ item.to_s.sub(/\A--?/, '') == @options[:unless].to_s.sub(/\A--?/, '')
187
+ end
188
188
  end
189
189
 
190
190
  # This option in a nice pretty string, including a short flag, long
@@ -303,7 +303,7 @@ class Slop
303
303
  lines.each do |line|
304
304
  opt, description = line.split(' ', 2)
305
305
  short, long = opt.split(',').map { |s| s.sub(/\A--?/, '') }
306
- argument = long && long[/\=$/]
306
+ argument = long && long[-1] == ?$
307
307
  long.sub!(/\=$/, '') if argument
308
308
  opts.on short, long, description, argument
309
309
  end
@@ -515,7 +515,6 @@ class Slop
515
515
  # @return [Slop::Option]
516
516
  def option(*args, &block)
517
517
  options = args.last.is_a?(Hash) ? args.pop : {}
518
-
519
518
  short, long, desc, arg, extras = clean_options(args)
520
519
 
521
520
  options.merge!(extras)
@@ -675,7 +674,7 @@ class Slop
675
674
  # @return [Array] A list of options missing from the parsed string
676
675
  # @since 2.1.0
677
676
  def missing
678
- @options.select { |opt| not present?(opt.key) }.map { |opt| opt.key }
677
+ @options.select { |opt| not present?(opt.key) }.map(&:key)
679
678
  end
680
679
 
681
680
  # Allows you to check whether an option was specified in the parsed list
@@ -689,14 +688,22 @@ class Slop
689
688
  # @see Slop#present?
690
689
  # @return [Boolean] true if this option is present, false otherwise
691
690
  def method_missing(meth, *args, &block)
692
- super unless meth.to_s[-1, 1] == '?'
693
- present = present? meth.to_s.chomp('?')
694
-
695
- (class << self; self; end).instance_eval do
696
- define_method(meth) { present }
691
+ meth = meth.to_s
692
+ if meth[-1] == ??
693
+ present?(meth.chop)
694
+ else
695
+ super
697
696
  end
697
+ end
698
698
 
699
- present
699
+ # Override this method so we can check if an option? method exists
700
+ def respond_to?(method)
701
+ method = method.to_s
702
+ if method[-1] == ?? and @options.any? { |o| o.key == method.chop }
703
+ true
704
+ else
705
+ super
706
+ end
700
707
  end
701
708
 
702
709
  # Check if an option is specified in the parsed list
@@ -988,11 +995,18 @@ class Slop
988
995
  def clean_options(args)
989
996
  options = []
990
997
  extras = {}
991
- extras[:as] = args.find { |c| c.is_a? Class }
992
- args.delete(extras[:as])
993
- extras.delete(:as) if extras[:as].nil?
998
+
999
+ if klass = args.find { |a| a.is_a?(Class) }
1000
+ extras[:as] = klass
1001
+ args.delete klass
1002
+ end
994
1003
 
995
1004
  short = args.first.to_s.sub(/\A--?/, '')
1005
+ if short.size == 2 && short[-1, 1] == '='
1006
+ extras[:argument] = true
1007
+ short.chop!
1008
+ end
1009
+
996
1010
  if short.size == 1
997
1011
  options.push short
998
1012
  args.shift
@@ -1001,18 +1015,21 @@ class Slop
1001
1015
  end
1002
1016
 
1003
1017
  long = args.first
1004
- boolean = [true, false].include? long
1005
-
1006
- if not boolean and long.to_s =~ /\A(?:--?)?[a-z_-]+\s[A-Z\s\[\]]+\z/
1007
- arg, help = args.shift.split(/ /, 2)
1008
- options.push arg.sub(/\A--?/, '')
1009
- extras[:optional] = help[0, 1] == '[' && help[-1, 1] == ']'
1010
- extras[:help] = help
1011
- elsif not boolean and long.to_s =~ /\A(?:--?)?[a-zA-Z][a-zA-Z0-9_-]+\=?\z/
1012
- extras[:argument] = true if long.to_s[-1, 1] == '='
1013
- options.push args.shift.to_s.sub(/\A--?/, '').sub(/\=\z/, '')
1014
- else
1018
+ if long.is_a?(TrueClass) || long.is_a?(FalseClass)
1015
1019
  options.push nil
1020
+ else
1021
+ case long.to_s
1022
+ when /\A(?:--?)?[a-z_-]+\s[A-Z\s\[\]]+\z/
1023
+ arg, help = args.shift.split(/ /, 2)
1024
+ extras[:optional] = help[0, 1] == '[' && help[-1, 1] == ']'
1025
+ extras[:help] = help
1026
+ options.push arg.sub(/\A--?/, '')
1027
+ when /\A(?:--?)?[a-zA-Z][a-zA-Z0-9_-]+\=?\z/
1028
+ extras[:argument] = true if long.to_s[-1, 1] == '='
1029
+ options.push args.shift.to_s.sub(/\A--?/, '').sub(/\=\z/, '')
1030
+ else
1031
+ options.push nil
1032
+ end
1016
1033
  end
1017
1034
 
1018
1035
  options.push args.first.respond_to?(:to_sym) ? args.shift : nil
data/slop.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'slop'
3
- s.version = '2.3.1'
3
+ s.version = '2.4.0'
4
4
  s.summary = 'Option gathering made easy'
5
5
  s.description = 'A simple DSL for gathering options and parsing the command line'
6
6
  s.author = 'Lee Jarvis'
data/test/option_test.rb CHANGED
@@ -28,6 +28,7 @@ class OptionTest < TestCase
28
28
  test 'expects an argument if long option is suffixed with =' do
29
29
  assert option(:f, :foo=).expects_argument?
30
30
  assert option('f', 'foo=').expects_argument?
31
+ assert option(:f=).expects_argument?
31
32
  end
32
33
 
33
34
  test 'accepts an optional argument if optional is true' do
data/test/slop_test.rb CHANGED
@@ -424,6 +424,22 @@ class SlopTest < TestCase
424
424
  assert_raises(Slop::MissingArgumentError) { slop.parse %w/-f --bar/ }
425
425
  end
426
426
 
427
+ test 'respond_to?' do
428
+ slop = Slop.new { on :f, :foo }
429
+ assert slop.respond_to?('foo?')
430
+ refute slop.respond_to?('foo')
431
+ end
432
+
433
+ test 'reusable slop object (ie not using define_method for present?())' do
434
+ slop = Slop.new { on :f, :foo }
435
+
436
+ slop.parse %w()
437
+ assert_equal false, slop.foo?
438
+
439
+ slop.parse %w( --foo )
440
+ assert_equal true, slop.foo?
441
+ end
442
+
427
443
  test 'custom IO object' do
428
444
  io = StringIO.new
429
445
  slop = Slop.new(:help => true, :io => io)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slop
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-11 00:00:00.000000000Z
12
+ date: 2011-11-26 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: A simple DSL for gathering options and parsing the command line
15
15
  email: lee@jarvis.co