@@ -461,6 +461,10 @@ def self.candidate(key, icase = false, pat = nil, &block)
461
461
candidates
462
462
end
463
463
464
+ def self . completable? ( key )
465
+ String . try_convert ( key ) or defined? ( key . id2name )
466
+ end
467
+
464
468
def candidate ( key , icase = false , pat = nil , &_ )
465
469
Completion . candidate ( key , icase , pat , &method ( :each ) )
466
470
end
@@ -544,11 +548,11 @@ def self.pattern
544
548
545
549
def initialize ( pattern = nil , conv = nil ,
546
550
short = nil , long = nil , arg = nil ,
547
- desc = ( [ ] if short or long ) , block = nil , &_block )
551
+ desc = ( [ ] if short or long ) , block = nil , values = nil , &_block )
548
552
raise if Array === pattern
549
553
block ||= _block
550
- @pattern , @conv , @short , @long , @arg , @desc , @block =
551
- pattern , conv , short , long , arg , desc , block
554
+ @pattern , @conv , @short , @long , @arg , @desc , @block , @values =
555
+ pattern , conv , short , long , arg , desc , block , values
552
556
end
553
557
554
558
#
@@ -581,11 +585,15 @@ def parse_arg(arg) # :nodoc:
581
585
# exception.
582
586
#
583
587
def conv_arg ( arg , val = [ ] ) # :nodoc:
588
+ v , = *val
584
589
if conv
585
590
val = conv . call ( *val )
586
591
else
587
592
val = proc { |v | v } . call ( *val )
588
593
end
594
+ if @values
595
+ @values . include? ( val ) or raise InvalidArgument , v
596
+ end
589
597
return arg , block , val
590
598
end
591
599
private :conv_arg
@@ -780,7 +788,7 @@ class PlacedArgument < self
780
788
# Returns nil if argument is not present or begins with '-' and is not '-'.
781
789
#
782
790
def parse ( arg , argv , &error )
783
- if !( val = arg ) and ! ( val = argv [ 0 ] ) &. match? ( /\A (?!-.)/ )
791
+ if !( val = arg ) and ( argv . empty? or /\A -./ =~ ( val = argv [ 0 ] ) )
784
792
return nil , block
785
793
end
786
794
opt = ( val = parse_arg ( val , &error ) ) [ 1 ]
@@ -1464,6 +1472,7 @@ def make_switch(opts, block = nil)
1464
1472
klass = nil
1465
1473
q , a = nil
1466
1474
has_arg = false
1475
+ values = nil
1467
1476
1468
1477
opts . each do |o |
1469
1478
# argument class
@@ -1477,7 +1486,7 @@ def make_switch(opts, block = nil)
1477
1486
end
1478
1487
1479
1488
# directly specified pattern(any object possible to match)
1480
- if ( ! ( String === o || Symbol === o ) ) and o . respond_to? ( :match )
1489
+ if ! Completion . completable? ( o ) and o . respond_to? ( :match )
1481
1490
pattern = notwice ( o , pattern , 'pattern' )
1482
1491
if pattern . respond_to? ( :convert )
1483
1492
conv = pattern . method ( :convert ) . to_proc
@@ -1492,6 +1501,11 @@ def make_switch(opts, block = nil)
1492
1501
when Proc , Method
1493
1502
block = notwice ( o , block , 'block' )
1494
1503
when Array , Hash
1504
+ if Array === o
1505
+ o , v = o . partition { |v | Completion . completable? ( v ) }
1506
+ values = notwice ( v , values , 'values' ) unless v . empty?
1507
+ next if o . empty?
1508
+ end
1495
1509
case pattern
1496
1510
when CompletingHash
1497
1511
when nil
@@ -1500,7 +1514,9 @@ def make_switch(opts, block = nil)
1500
1514
else
1501
1515
raise ArgumentError , "argument pattern given twice"
1502
1516
end
1503
- o . each { |pat , *v | pattern [ pat . to_s ] = v . fetch ( 0 ) { pat } }
1517
+ o . each { |pat , *v | pattern [ pat ] = v . fetch ( 0 ) { pat } }
1518
+ when Range
1519
+ values = notwice ( o , values , 'values' )
1504
1520
when Module
1505
1521
raise ArgumentError , "unsupported argument type: #{ o } " , ParseError . filter_backtrace ( caller ( 4 ) )
1506
1522
when *ArgumentStyle . keys
@@ -1568,12 +1584,18 @@ def make_switch(opts, block = nil)
1568
1584
end
1569
1585
1570
1586
default_pattern , conv = search ( :atype , default_style . pattern ) unless default_pattern
1587
+ if Range === values and klass
1588
+ unless ( !values . begin or klass === values . begin ) and
1589
+ ( !values . end or klass === values . end )
1590
+ raise ArgumentError , "range does not match class"
1591
+ end
1592
+ end
1571
1593
if !( short . empty? and long . empty? )
1572
1594
if has_arg and default_style == Switch ::NoArgument
1573
1595
default_style = Switch ::RequiredArgument
1574
1596
end
1575
1597
s = ( style || default_style ) . new ( pattern || default_pattern ,
1576
- conv , sdesc , ldesc , arg , desc , block )
1598
+ conv , sdesc , ldesc , arg , desc , block , values )
1577
1599
elsif !block
1578
1600
if style or pattern
1579
1601
raise ArgumentError , "no switch given" , ParseError . filter_backtrace ( caller )
@@ -1582,7 +1604,7 @@ def make_switch(opts, block = nil)
1582
1604
else
1583
1605
short << pattern
1584
1606
s = ( style || default_style ) . new ( pattern ,
1585
- conv , nil , nil , arg , desc , block )
1607
+ conv , nil , nil , arg , desc , block , values )
1586
1608
end
1587
1609
return s , short , long ,
1588
1610
( not_style . new ( not_pattern , not_conv , sdesc , ldesc , nil , desc , block ) if not_style ) ,
0 commit comments