ame 0.1.1 → 1.0.1

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 (90) hide show
  1. checksums.yaml +7 -0
  2. data/README +541 -3
  3. data/Rakefile +15 -6
  4. data/lib/ame-1.0.rb +31 -0
  5. data/lib/ame-1.0/argument.rb +63 -0
  6. data/lib/ame-1.0/arguments.rb +44 -0
  7. data/lib/ame-1.0/arguments/complete.rb +37 -0
  8. data/lib/ame-1.0/arguments/optional.rb +34 -0
  9. data/lib/ame-1.0/arguments/undefined.rb +71 -0
  10. data/lib/ame-1.0/class.rb +436 -0
  11. data/lib/ame-1.0/flag.rb +101 -0
  12. data/lib/{ame → ame-1.0}/help.rb +1 -1
  13. data/lib/ame-1.0/help/delegate.rb +19 -0
  14. data/lib/ame-1.0/help/terminal.rb +132 -0
  15. data/lib/ame-1.0/method.rb +75 -0
  16. data/lib/ame-1.0/method/undefined.rb +184 -0
  17. data/lib/ame-1.0/methods.rb +40 -0
  18. data/lib/ame-1.0/multioption.rb +36 -0
  19. data/lib/ame-1.0/option.rb +37 -0
  20. data/lib/ame-1.0/optional.rb +31 -0
  21. data/lib/ame-1.0/options.rb +68 -0
  22. data/lib/ame-1.0/options/undefined.rb +114 -0
  23. data/lib/ame-1.0/root.rb +174 -0
  24. data/lib/ame-1.0/splat.rb +16 -0
  25. data/lib/ame-1.0/splus.rb +22 -0
  26. data/lib/ame-1.0/switch.rb +39 -0
  27. data/lib/ame-1.0/types.rb +60 -0
  28. data/lib/ame-1.0/types/boolean.rb +13 -0
  29. data/lib/ame-1.0/types/enumeration.rb +40 -0
  30. data/lib/ame-1.0/types/float.rb +11 -0
  31. data/lib/{ame → ame-1.0}/types/integer.rb +3 -3
  32. data/lib/{ame → ame-1.0}/types/string.rb +2 -2
  33. data/lib/ame-1.0/types/symbol.rb +9 -0
  34. data/lib/ame-1.0/version.rb +62 -0
  35. data/test/unit/ame-1.0.rb +4 -0
  36. data/test/unit/ame-1.0/argument.rb +46 -0
  37. data/test/unit/ame-1.0/arguments.rb +63 -0
  38. data/test/unit/ame-1.0/arguments/complete.rb +4 -0
  39. data/test/unit/ame-1.0/arguments/optional.rb +4 -0
  40. data/test/unit/ame-1.0/arguments/undefined.rb +63 -0
  41. data/test/unit/ame-1.0/class.rb +4 -0
  42. data/test/unit/ame-1.0/flag.rb +31 -0
  43. data/test/unit/ame-1.0/help.rb +4 -0
  44. data/test/unit/ame-1.0/help/delegate.rb +4 -0
  45. data/test/unit/{ame/help/console.rb → ame-1.0/help/terminal.rb} +34 -23
  46. data/test/unit/ame-1.0/method.rb +4 -0
  47. data/test/unit/ame-1.0/method/undefined.rb +33 -0
  48. data/test/unit/ame-1.0/methods.rb +9 -0
  49. data/test/unit/ame-1.0/multioption.rb +4 -0
  50. data/test/unit/ame-1.0/option.rb +11 -0
  51. data/test/unit/ame-1.0/optional.rb +9 -0
  52. data/test/unit/ame-1.0/options.rb +149 -0
  53. data/test/unit/ame-1.0/options/undefined.rb +33 -0
  54. data/test/unit/ame-1.0/root.rb +4 -0
  55. data/test/unit/ame-1.0/splat.rb +9 -0
  56. data/test/unit/ame-1.0/splus.rb +4 -0
  57. data/test/unit/ame-1.0/switch.rb +15 -0
  58. data/test/unit/ame-1.0/types.rb +4 -0
  59. data/test/{ame → unit/ame-1.0}/types/boolean.rb +0 -0
  60. data/test/unit/ame-1.0/types/enumeration.rb +4 -0
  61. data/test/unit/ame-1.0/types/float.rb +7 -0
  62. data/test/{ame → unit/ame-1.0}/types/integer.rb +0 -0
  63. data/test/{ame → unit/ame-1.0}/types/string.rb +0 -0
  64. data/test/unit/ame-1.0/types/symbol.rb +5 -0
  65. data/test/unit/ame-1.0/version.rb +4 -0
  66. metadata +690 -60
  67. data/lib/ame.rb +0 -26
  68. data/lib/ame/argument.rb +0 -56
  69. data/lib/ame/arguments.rb +0 -65
  70. data/lib/ame/class.rb +0 -117
  71. data/lib/ame/help/console.rb +0 -96
  72. data/lib/ame/method.rb +0 -94
  73. data/lib/ame/methods.rb +0 -30
  74. data/lib/ame/option.rb +0 -50
  75. data/lib/ame/options.rb +0 -102
  76. data/lib/ame/root.rb +0 -57
  77. data/lib/ame/splat.rb +0 -12
  78. data/lib/ame/types.rb +0 -29
  79. data/lib/ame/types/array.rb +0 -16
  80. data/lib/ame/types/boolean.rb +0 -16
  81. data/lib/ame/version.rb +0 -5
  82. data/test/ame/types/array.rb +0 -13
  83. data/test/unit/ame/argument.rb +0 -66
  84. data/test/unit/ame/arguments.rb +0 -106
  85. data/test/unit/ame/method.rb +0 -40
  86. data/test/unit/ame/methods.rb +0 -10
  87. data/test/unit/ame/option.rb +0 -75
  88. data/test/unit/ame/options.rb +0 -136
  89. data/test/unit/ame/root.rb +0 -15
  90. data/test/unit/ame/splat.rb +0 -11
@@ -0,0 +1,101 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Represents a boolean option to a {Method} that doesn’t take an argument,
4
+ # though an argument is actually allowed if it’s made explicit by following the
5
+ # option name with a ‘=’ character and the argument value. Does the potential
6
+ # processing of the argument or simply returns the inverse {#default} value of
7
+ # the flag.
8
+ # @api developer
9
+ class Ame::Flag
10
+ # @api internal
11
+ # @param [String] short
12
+ # @param [String] long
13
+ # @param [Boolean] default
14
+ # @param [String] description
15
+ # @yield [?]
16
+ # @yieldparam [Hash<String, Object>] options
17
+ # @yieldparam [Boolean] value
18
+ # @raise [ArgumentError] If SHORT and LONG are #strip#empty?
19
+ # @raise [ArgumentError] If SHORT#strip#length > 1
20
+ def initialize(short, long, default, description, &validate)
21
+ @short, @long, @default, @description, @validate =
22
+ (s = short.strip).empty? ? nil : s, (l = long.strip).empty? ? nil : l,
23
+ default, description, validate || proc{ |_, a| a }
24
+ raise ArgumentError, 'both short and long can’t be empty' if
25
+ @short.nil? and @long.nil?
26
+ raise ArgumentError, 'short can’t be longer than 1: %s' % @short if
27
+ @short and @short.length > 1
28
+ end
29
+
30
+ # Invokes the optional block passed to the receiver when it was created for
31
+ # additional validation and parsing after optionally parsing one or more of
32
+ # the ARGUMENTS passed to it (see subclasses’ {#parse} methods for their
33
+ # behaviour).
34
+ # @api internal
35
+ # @param [Hash<String, Object>] options
36
+ # @param [Array<String>] arguments
37
+ # @param [String] name
38
+ # @raise [MissingArgument] If a required argument to an option is missing
39
+ # @raise [MalformedArgument] If an argument to an option can’t be parsed
40
+ # @return [Boolean]
41
+ def process(options, arguments, name, explicit)
42
+ @validate.call(options, parse(arguments, explicit))
43
+ rescue Ame::MalformedArgument, ArgumentError, TypeError => e
44
+ raise Ame::MalformedArgument, '%s: %s' % [name, e]
45
+ end
46
+
47
+ # Invokes {#process} with arguments depending on whether REMAINDER, which is
48
+ # any content following a short option, should be seen as an argument to the
49
+ # receiver or not (see subclasses’ {#process_combined} methods for their
50
+ # behaviour), returning the result of {#process} and REMAINDER if it was
51
+ # used, or an empty String if it was.
52
+ # @api internal
53
+ # @param (see #process)
54
+ # @param [String] remainder
55
+ # @return [[Boolean, String]]
56
+ def process_combined(options, arguments, name, remainder)
57
+ [process(options, arguments, name, nil), remainder]
58
+ end
59
+
60
+ # @return [String] The long or short name of the option
61
+ def name
62
+ @name ||= names.first
63
+ end
64
+
65
+ # @return [Array<String>] The long and/or short name of the option
66
+ def names
67
+ @names ||= [long, short].reject{ |e| e.nil? }
68
+ end
69
+
70
+ # @return True if the receiver shouldn’t be included in the Hash of option
71
+ # names and their values
72
+ def ignored?
73
+ default.nil?
74
+ end
75
+
76
+ # @return [String] The short name of the receiver
77
+ attr_reader :short
78
+
79
+ # @return [String] The long name of the receiver
80
+ attr_reader :long
81
+
82
+ # @return [Boolean] The default value of the receiver
83
+ attr_reader :default
84
+
85
+ # @return [String] The description of the receiver
86
+ attr_reader :description
87
+
88
+ private
89
+
90
+ # Returns the parsed value of EXPLICIT, or the inverse of {#default} if nil.
91
+ # Should be overridden by subclasses that want different behaviour for
92
+ # missing arguments.
93
+ # @api internal
94
+ # @param [Array<String>] arguments
95
+ # @param [String, nil] explicit
96
+ # @return [Boolean]
97
+ # @raise [MalformedArgument] If EXPLICIT is non-nil and can’t be parsed
98
+ def parse(arguments, explicit)
99
+ explicit ? Ame::Types[TrueClass].parse(explicit) : !default
100
+ end
101
+ end
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ # Namespace for help output.
3
4
  module Ame::Help
4
- autoload :Console, 'ame/help/console'
5
5
  end
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Delegates help output requests to another help output.
4
+ # @api internal
5
+ class Ame::Help::Delegate
6
+ def initialize(help)
7
+ @help = help
8
+ end
9
+
10
+ def dispatch(method, klass)
11
+ @help.dispatch method, klass
12
+ self
13
+ end
14
+
15
+ def method(method)
16
+ @help.method method
17
+ self
18
+ end
19
+ end
@@ -0,0 +1,132 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Outputs help requests to a pair of IO objects, defaulting to `$stdout` and
4
+ # `$stderr`. An instance of this class is used by default for outputting help
5
+ # requests from {Root}, but can be overridden by invoking {Root.help} with
6
+ # another object (such as an instance of this class that’s been constructed
7
+ # with different parameters).
8
+ # @api developer/user
9
+ class Ame::Help::Terminal
10
+ # Sets up help requests to be made to OUTPUT ({#dispatch}, {#method}, and
11
+ # {#version}) and ERROR ({#error}), as well as specifying whether to
12
+ # EXIT_ON_ERROR or not, see {#error}.
13
+ # @param [#puts] output
14
+ # @param [#puts] error
15
+ # @param [Boolean] exit_on_error
16
+ def initialize(output = $stdout, error = $stderr, exit_on_error = true)
17
+ @output, @error, @exit_on_error = output, error, exit_on_error
18
+ end
19
+
20
+ # Outputs a help request for a {Class.dispatch} METHOD to KLASS, displaying
21
+ # all options and arguments to the method and listing the possible dispatch
22
+ # methods.
23
+ # @param [Method] method
24
+ # @param [Class] klass
25
+ # @return [self]
26
+ def dispatch(method, klass)
27
+ output(method_s(method).tap{ |result|
28
+ append_group result, 'Methods', klass.methods.sort_by{ |m| m.name } do |m|
29
+ m.name
30
+ end
31
+ })
32
+ end
33
+
34
+ # Outputs a help request for METHOD, displaying all its options and
35
+ # arguments.
36
+ # @param [Method] method
37
+ # @return [self]
38
+ def method(method)
39
+ output(method_s(method))
40
+ end
41
+
42
+ # Outputs VERSION information for METHOD.
43
+ # @param [Method] method
44
+ # @param [String] version
45
+ # @return [self]
46
+ def version(method, version)
47
+ output('%s %s' % [method.name, version])
48
+ end
49
+
50
+ # Outputs ERROR that occurred while processing METHOD.
51
+ # @raise [SystemExit] If exit_on_error was given as true to the receiver’s
52
+ # constructor
53
+ # @raise [error] If exit_on_error wasn’t given as true to the receiver’s
54
+ # constructor
55
+ def error(method, error)
56
+ errput '%s: %s' % [method, error]
57
+ exit 1 if @exit_on_error
58
+ raise error
59
+ end
60
+
61
+ private
62
+
63
+ def output(string)
64
+ @output.puts string
65
+ self
66
+ end
67
+
68
+ def errput(string)
69
+ @error.puts string
70
+ self
71
+ end
72
+
73
+ def method_s(method)
74
+ ['Usage:'].tap{ |result|
75
+ append result, ' ', method.qualified_name
76
+ append result, ' ', method.options.count > 0 ? '[OPTIONS]...' : ''
77
+ append result, ' ', method.arguments.map{ |a|
78
+ case a
79
+ when Ame::Splat then '[%s]...'
80
+ when Ame::Splus then '%s...'
81
+ when Ame::Optional then '[%s]'
82
+ else '%s'
83
+ end % a
84
+ }.join(' ')
85
+ result << "\n"
86
+ append result, ' ', method.description
87
+ append_group result, 'Arguments', method.arguments do |argument|
88
+ case argument
89
+ when Ame::Splat then '[%s]...' % argument
90
+ when Ame::Splus then '%s...' % argument
91
+ when Ame::Optional then '[%s=%s]' % [argument, argument.default]
92
+ else argument.to_s
93
+ end
94
+ end
95
+ os = method.options.select{ |o| o.description }.sort_by{ |o| (o.short or o.long).to_s }
96
+ short = os.any?{ |o| o.short }
97
+ append_group result, 'Options', os do |o|
98
+ case o
99
+ when Ame::Multioption then '%s*' % option(o, short)
100
+ when Ame::Option then option(o, short)
101
+ when Ame::Switch then '%s[=%s]' % [flag(o, short), o.argument]
102
+ else flag(o, short)
103
+ end
104
+ end
105
+ }.join('')
106
+ end
107
+
108
+ def append(result, prefix, string)
109
+ result << prefix << string unless string.empty?
110
+ end
111
+
112
+ def append_group(result, heading, objects)
113
+ strings = objects.map{ |o| [o, yield(o)] }
114
+ longest = strings.map{ |_, s| s.length }.max
115
+ append result, "\n\n%s:\n" % heading,
116
+ strings.map{ |o, s| ' %-*s %s' % [longest, s, o.description] }.join("\n")
117
+ end
118
+
119
+ def flag(option, short)
120
+ if option.short and option.long
121
+ '-%s, --%s' % [option.short, option.long]
122
+ elsif option.short
123
+ '-%s' % option.short
124
+ else
125
+ '%s--%s' % [short ? ' ' : '', option.long]
126
+ end
127
+ end
128
+
129
+ def option(option, short)
130
+ '%s%s%s' % [flag(option, short), option.long ? '=' : '', option.argument]
131
+ end
132
+ end
@@ -0,0 +1,75 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # A method in its defined state.
4
+ # @api developer
5
+ class Ame::Method
6
+ class << self
7
+ # @param [String] name
8
+ # @return [Symbol] The Ruby version of NAME, possibly the name of the
9
+ # method given on the command-line, replacing any ‘-’ with ‘_’.
10
+ def ruby_name(name)
11
+ name.gsub('-', '_').to_sym
12
+ end
13
+
14
+ # @param [Symbol] ruby_name
15
+ # @return [String] The command-line version of RUBY_NAME, replacing any ‘_’
16
+ # with ‘-’
17
+ def name(ruby_name)
18
+ ruby_name.to_s.gsub('_', '-')
19
+ end
20
+ end
21
+
22
+ def initialize(ruby_name, klass, description, options, arguments)
23
+ @ruby_name, @class, @description, @options, @arguments =
24
+ ruby_name, klass, description, options, arguments
25
+ end
26
+
27
+ # Process ARGUMENTS as a set of {Options} and {Arguments}, then {#call} the
28
+ # receiver’s method on INSTANCE with them.
29
+ # @api internal
30
+ # @param [Class] instance
31
+ # @param [Array<String>] arguments
32
+ # @raise (see Options#process)
33
+ # @raise (see Arguments#process)
34
+ # @return [self]
35
+ def process(instance, arguments)
36
+ options, remainder = @options.process(arguments)
37
+ call(instance, @arguments.process(options, remainder), options)
38
+ end
39
+
40
+ # Call the receiver’s method on INSTANCE with ARGUMENTS and OPTIONS,
41
+ # retrieving any default values for them if they’re nil.
42
+ # @api internal
43
+ # @param [Class] instance
44
+ # @param [Array<Object>, nil] arguments
45
+ # @param [Hash<String, Object>] options
46
+ # @raise (see Options#process)
47
+ # @raise (see Arguments#process)
48
+ # @return [self]
49
+ def call(instance, arguments = nil, options = nil)
50
+ options, _ = @options.process([]) unless options
51
+ arguments ||= @arguments.process(options, [])
52
+ instance.send @ruby_name, *(arguments + (options.empty? ? [] : [options]))
53
+ self
54
+ end
55
+
56
+ # @return [String] The description of the receiver
57
+ attr_reader :description
58
+
59
+ # @return [Options] The options of the receiver
60
+ attr_reader :options
61
+
62
+ # @return [Arguments] The arguments of the receiver
63
+ attr_reader :arguments
64
+
65
+ # @return [String] The command-line name of the receiver
66
+ def name
67
+ @name ||= self.class.name(@ruby_name)
68
+ end
69
+
70
+ # @return [String] The full command-line name of the receiver, including the
71
+ # class that this method belongs to’s {Class.fullname}
72
+ def qualified_name
73
+ [@class.fullname, name].reject(&:empty?).join(' ')
74
+ end
75
+ end
@@ -0,0 +1,184 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # A {Method} in its undefined state. This class is used to construct the
4
+ # method before it gets defined, setting up a description, specifying that
5
+ # options_must_precede_arguments, adding flags, toggles, switches, options,
6
+ # multioptions, arguments, optional arguments, splats, spluses, and finally
7
+ # defining it.
8
+ # @api developer
9
+ class Ame::Method::Undefined
10
+ # Sets up an as yet undefined method on KLASS.
11
+ # @api internal
12
+ # @param [Class] klass
13
+ def initialize(klass)
14
+ @class = klass
15
+ @description = nil
16
+ @options = Ame::Options::Undefined.new
17
+ @arguments = Ame::Arguments::Undefined.new
18
+ end
19
+
20
+ # Sets the DESCRIPTION of the method, or returns it if DESCRIPTION is nil.
21
+ # The description is used in help output and similar circumstances.
22
+ # @api internal
23
+ # @param [String, nil] description
24
+ # @return [String]
25
+ def description(description = nil)
26
+ return @description unless description
27
+ @description = description
28
+ self
29
+ end
30
+
31
+ # Forces options to the method to precede any arguments to be processed
32
+ # correctly.
33
+ # @api internal
34
+ # @return [self]
35
+ def options_must_precede_arguments
36
+ @options.options_must_precede_arguments
37
+ self
38
+ end
39
+
40
+ # Delegates {Class.flag} to {Options::Undefined#flag}.
41
+ # @api internal
42
+ # @param (see Options::Undefined#flag)
43
+ # @yield (see Options::Undefined#flag)
44
+ # @yieldparam (see Options::Undefined#flag)
45
+ # @raise (see Options::Undefined#flag)
46
+ # @return [self]
47
+ def flag(short, long, default, description, &validate)
48
+ @options.flag short, long, default, description, &validate
49
+ self
50
+ end
51
+
52
+ # Delegates {Class.toggle} to {Options::Undefined#toggle}.
53
+ # @api internal
54
+ # @param (see Options::Undefined#toggle)
55
+ # @yield (see Options::Undefined#toggle)
56
+ # @yieldparam (see Options::Undefined#toggle)
57
+ # @raise (see Options::Undefined#toggle)
58
+ # @return [self]
59
+ def toggle(short, long, default, description, &validate)
60
+ @options.toggle short, long, default, description, &validate
61
+ self
62
+ end
63
+
64
+ # Delegates {Class.switch} to {Options::Undefined#switch}.
65
+ # @api internal
66
+ # @param (see Options::Undefined#switch)
67
+ # @yield (see Options::Undefined#switch)
68
+ # @yieldparam (see Options::Undefined#switch)
69
+ # @raise (see Options::Undefined#switch)
70
+ # @return [self]
71
+ def switch(short, long, argument, default, argument_default, description, &validate)
72
+ @options.switch short, long, argument, default, argument_default, description, &validate
73
+ self
74
+ end
75
+
76
+ # Delegates {Class.option} to {Options::Undefined#option}.
77
+ # @api internal
78
+ # @param (see Options::Undefined#option)
79
+ # @yield (see Options::Undefined#option)
80
+ # @yieldparam (see Options::Undefined#option)
81
+ # @raise (see Options::Undefined#option)
82
+ # @return [self]
83
+ def option(short, long, argument, default, description, &validate)
84
+ @options.option short, long, argument, default, description, &validate
85
+ self
86
+ end
87
+
88
+ # Delegates {Class.multioption} to {Options::Undefined#multioption}.
89
+ # @api internal
90
+ # @param (see Options::Undefined#multioption)
91
+ # @yield (see Options::Undefined#multioption)
92
+ # @yieldparam (see Options::Undefined#multioption)
93
+ # @raise (see Options::Undefined#multioption)
94
+ # @return [self]
95
+ def multioption(short, long, argument, type, description, &validate)
96
+ @options.multioption short, long, argument, type, description, &validate
97
+ self
98
+ end
99
+
100
+ # Delegates {Class.argument} to {Arguments::Undefined#argument}.
101
+ # @api internal
102
+ # @param (see Arguments::Undefined#argument)
103
+ # @yield (see Arguments::Undefined#argument)
104
+ # @yieldparam (see Arguments::Undefined#argument)
105
+ # @raise (see Arguments::Undefined#argument)
106
+ # @raise (see Arguments::Optional#argument)
107
+ # @raise (see Arguments::Complete#argument)
108
+ # @return [self]
109
+ def argument(name, type, description, &validate)
110
+ @arguments.argument(name, type, description, &validate)
111
+ self
112
+ end
113
+
114
+ # Delegates {Class.argument} to {Arguments::Undefined#optional} or
115
+ # {Arguments::Optional#optional}.
116
+ # @api internal
117
+ # @param (see Arguments::Undefined#optional)
118
+ # @yield (see Arguments::Undefined#optional)
119
+ # @yieldparam (see Arguments::Undefined#optional)
120
+ # @param (see Arguments::Undefined#optional)
121
+ # @raise (see Arguments::Undefined#optional)
122
+ # @raise (see Arguments::Complete#optional)
123
+ # @return [self]
124
+ def optional(name, default, description, &validate)
125
+ @arguments = @arguments.optional(name, default, description, &validate)
126
+ self
127
+ end
128
+
129
+ # Delegates {Class.argument} to {Arguments::Undefined#splat}.
130
+ # @api internal
131
+ # @param (see Arguments::Undefined#splat)
132
+ # @option (see Arguments::Undefined#splat)
133
+ # @yield (see Arguments::Undefined#splat)
134
+ # @yieldparam (see Arguments::Undefined#splat)
135
+ # @raise (see Arguments::Undefined#splat)
136
+ # @raise (see Arguments::Complete#splat)
137
+ # @return [self]
138
+ def splat(name, type, description, &validate)
139
+ @arguments = @arguments.splat(name, type, description, &validate)
140
+ self
141
+ end
142
+
143
+ # Delegates {Class.argument} to {Arguments::Undefined#splus}.
144
+ # @api internal
145
+ # @param (see Arguments::Undefined#splus)
146
+ # @option (see Arguments::Undefined#splus)
147
+ # @yield (see Arguments::Undefined#splus)
148
+ # @yieldparam (see Arguments::Undefined#splus)
149
+ # @raise (see Arguments::Undefined#splus)
150
+ # @raise (see Arguments::Optional#splus)
151
+ # @raise (see Arguments::Complete#splus)
152
+ # @return [self]
153
+ def splus(name, type, description, &validate)
154
+ @arguments = @arguments.splus(name, type, description, &validate)
155
+ self
156
+ end
157
+
158
+ # @api internal
159
+ # @return [Method] The method RUBY_NAME after adding a “help” flag that’ll
160
+ # display help via {Class.help}#method and raise {AbortAllProcessing}
161
+ def define(ruby_name)
162
+ flag '', 'help', nil, 'Display help for this method' do
163
+ @class.help.method @class.methods[Ame::Method.name(ruby_name)]
164
+ throw Ame::AbortAllProcessing
165
+ end unless @options.include? 'help'
166
+ Ame::Method.new(ruby_name, @class, @description, @options.define, @arguments.define)
167
+ end
168
+
169
+ # @param [String] option
170
+ # @return [Boolean] True if OPTION has been defined on the receiver
171
+ def option?(option)
172
+ @options.include? option
173
+ end
174
+
175
+ # @return [Boolean] True if any arguments have been defined on the receiver
176
+ def arguments?
177
+ not @arguments.empty?
178
+ end
179
+
180
+ # @return [Boolean] True if a description has been defined on the receiver
181
+ def valid?
182
+ not description.nil?
183
+ end
184
+ end