From 5705fa3546610df47ab103c6967142e74781603f Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Tue, 26 Oct 2021 13:58:12 -0500 Subject: [PATCH 1/5] Enhanced RDoc for GetoptLong --- lib/getoptlong.rb | 573 +++++++++++++++++++++++++++++++++------------- 1 file changed, 413 insertions(+), 160 deletions(-) diff --git a/lib/getoptlong.rb b/lib/getoptlong.rb index d3fff34..c306fca 100644 --- a/lib/getoptlong.rb +++ b/lib/getoptlong.rb @@ -6,83 +6,367 @@ # # You may redistribute and/or modify this library under the same license # terms as Ruby. + +# \Class \GetoptLong provides command-line parsing both for options +# and for regular arguments. # -# See GetoptLong for documentation. +# Using \GetoptLong, you can define command-line options for your program. +# The program can then capture and respond to whatever options +# are included in the command that executes the program. # -# Additional documents and the latest version of `getoptlong.rb' can be -# found at http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/ - -# The GetoptLong class allows you to parse command line options similarly to -# the GNU getopt_long() C library call. Note, however, that GetoptLong is a -# pure Ruby implementation. +# A simple example: file simple.rb: +# +# :include: ../doc/simple.rb +# +# If you are somewhat familiar with command-line options, +# you may want to skip to this +# {full example}[#class-GetoptLong-label-Full+Example]. +# +# == Options +# +# A \GetoptLong option has: +# +# - A string option name. +# - Zero or more string aliases for the name. +# - An option type. +# +# An option may be defined by calling singleton method GetoptLong.new. +# Command-line options may then be processed by calling other methods +# such as GetoptLong#each. +# +# === Option Name and Aliases +# +# In the array that defines an option, +# the first element is the string the option name. +# Often the name takes the 'long' form, beginning with two hyphens. +# +# The option name may have any number of aliases, +# which are defined by additional string elements. +# +# The name and each alias must be of one of two forms: +# +# - Two hyphens, followed by one or more letters. +# - One hyphen, followed by a single letter. +# +# File aliases.rb: +# +# :include: ../doc/aliases.rb +# +# On the command line, an option may be cited by its name, +# or by any of its aliases; +# the parsed option always reports the name, not an alias: +# +# $ ruby aliases.rb -a -p --xxx --aaa -x +# +# Output: +# +# ["--xxx", ""] +# ["--xxx", ""] +# ["--xxx", ""] +# ["--xxx", ""] +# ["--xxx", ""] +# +# +# An option may also be cited by an abbreviation of its name or any alias, +# as long as that abbreviation is unique among the options. +# +# File abbrev.rb: +# +# :include: ../doc/abbrev.rb +# +# Command line: +# +# $ ruby abbrev.rb --xxx --xx --xyz --xy +# +# Output: +# +# ["--xxx", ""] +# ["--xxx", ""] +# ["--xyz", ""] +# ["--xyz", ""] +# +# This command line raises GetoptLong::AmbiguousOption: +# +# $ ruby abbrev.rb --x +# +# === Repetition +# +# An option may be cited more than once: +# +# $ ruby abbrev.rb --xxx --xyz --xxx --xyz +# +# Output: +# +# ["--xxx", ""] +# ["--xyz", ""] +# ["--xxx", ""] +# ["--xyz", ""] +# +# === Protected Options +# +# A command-line option that appears anywhere after the token -- +# is _protected_, and is not processed as an option: +# +# $ ruby abbrev.rb --xxx --xyz -- --xxx --xyz +# +# Output: +# +# ["--xxx", ""] +# ["--xyz", ""] +# +# === Option Types +# +# Each option definition includes an option type, +# which controls whether the option takes an argument on the command line. +# +# File types.rb: +# +# :include: ../doc/types.rb +# +# Note that an option type has to do with the option argument +# (whether it is required, optional, or forbidden), +# not with whether the option itself is required. +# +# ==== Option with Required Argument +# +# An option of type GetoptLong::REQUIRED_ARGUMENT: +# must be followed by an argument, which is associated with that option: +# +# $ ruby types.rb --xxx foo +# +# +# Output: +# +# ["--xxx", "foo"] +# +# If the option is not last, its argument is whatever follows it +# (even if the argument looks like another option): +# +# $ ruby types.rb --xxx --yyy +# +# Output: +# +# ["--xxx", "--yyy"] +# +# If the option is last, an exception is raised: +# +# $ ruby types.rb +# # Raises GetoptLong::MissingArgument +# +# ==== Option with Optional Argument +# +# An option of type GetoptLong::OPTIONAL_ARGUMENT: +# may be followed by an argument, which if given is associated with that option. +# +# If the option is last, it does not have an argument: +# +# $ ruby types.rb --yyy +# +# Output: +# +# ["--yyy", ""] +# +# If the option is followed by another option, it does not have an argument: +# +# $ ruby types.rb --yyy --zzz +# +# Output: +# +# ["--yyy", ""] +# ["--zzz", ""] +# +# Otherwise the option is followed by its argument, which is associated +# with that option: +# +# $ ruby types.rb --yyy foo +# +# Output: +# +# ["--yyy", "foo"] +# +# ==== Option with No Argument +# +# An option of type GetoptLong::NO_ARGUMENT takes no argument: +# +# ruby types.rb --zzz foo +# +# Output: +# +# ["--zzz", ""] +# +# === ARGV +# +# \GetoptLong does not process the command line itself, +# but instead processes array ARGV (which is derived from the command line). +# This processing is done either with method #each and a block, +# or with method #get. +# +# Before the processing, ARGV includes all words from the command line. +# During processing, each found option is removed, along with its argument +# if there is one. +# After processing, each remaining element was neither an option +# nor the argument for an option. +# +# File argv.rb: +# +# :include: ../doc/argv.rb +# +# Command line: # -# GetoptLong allows for POSIX-style options like --file as well -# as single letter options like -f +# $ ruby argv.rb --xxx Foo --yyy Bar Baz --zzz Bat Bam # -# The empty option -- (two minus symbols) is used to end option -# processing. This can be particularly important if options have optional -# arguments. +# Output: # -# Here is a simple example of usage: +# Original ARGV: ["--xxx", "Foo", "--yyy", "Bar", "Baz", "--zzz", "Bat", "Bam"] +# ["--xxx", "Foo"] +# ["--yyy", "Bar"] +# ["--zzz", ""] +# Remaining ARGV: ["Baz", "Bat", "Bam"] # -# require 'getoptlong' +# === Ordering # -# opts = GetoptLong.new( -# [ '--help', '-h', GetoptLong::NO_ARGUMENT ], -# [ '--repeat', '-n', GetoptLong::REQUIRED_ARGUMENT ], -# [ '--name', GetoptLong::OPTIONAL_ARGUMENT ] -# ) +# There are three settings that control the way the command line +# is interpreted: # -# dir = nil -# name = nil -# repetitions = 1 -# opts.each do |opt, arg| -# case opt -# when '--help' -# puts <<-EOF -# hello [OPTION] ... DIR +# - +PERMUTE+. +# - +REQUIRE_ORDER+. +# - +RETURN_IN_ORDER+. # +# The initial setting for a new \GetoptLong object is +REQUIRE_ORDER+ +# if environment variable +POSIXLY_CORRECT+ is defined, +PERMUTE+ otherwise. +# +# ==== PERMUTE Ordering +# +# In the +PERMUTE+ ordering, command-line options and other, non-option, +# command-line arguments may appear in any order and any mixture. +# +# File permute.rb: +# +# :include: ../doc/permute.rb +# +# Command line: +# +# $ ruby permute.rb Foo --zzz Bar --xxx Baz --yyy Bat Bam --xxx Bag Bah +# +# Output: +# +# Original ARGV: ["Foo", "--zzz", "Bar", "--xxx", "Baz", "--yyy", "Bat", "Bam", "--xxx", "Bag", "Bah"] +# ["--zzz", ""] +# ["--xxx", "Baz"] +# ["--yyy", "Bat"] +# ["--xxx", "Bag"] +# Remaining ARGV: ["Foo", "Bar", "Bam", "Bah"] +# +# ==== REQUIRE_ORDER Ordering +# +# In the +REQUIRE_ORDER+ ordering, all options precede all non-options; +# that is, each command-line word after the first non-option word +# is treated as a non-option word (even if it begins with a hyphen). +# +# File require_order.rb: +# +# :include: ../doc/require_order.rb +# +# Command line: +# +# $ ruby require_order.rb --xxx Foo Bar --xxx Baz --yyy Bat -zzz +# +# Output: +# +# Original ARGV: ["--xxx", "Foo", "Bar", "--xxx", "Baz", "--yyy", "Bat", "-zzz"] +# ["--xxx", "Foo"] +# Remaining ARGV: ["Bar", "--xxx", "Baz", "--yyy", "Bat", "-zzz"] +# +# ==== RETURN_IN_ORDER Ordering +# +# In the +RETURN_IN_ORDER+ ordering, every command-line word is treated as an option. +# A word that begins with a hyphen (or two) is treated in the usual way; +# a word +word+ that does not so begin is treated as an option +# whose name is an empty string, and whose value is +word+. +# +# File return_in_order.rb: +# +# :include: ../doc/return_in_order.rb +# +# Command line: +# +# $ ruby return_in_order.rb Foo --xxx Bar Baz --zzz Bat Bam +# +# Output: +# +# Original ARGV: ["Foo", "--xxx", "Bar", "Baz", "--zzz", "Bat", "Bam"] +# ["", "Foo"] +# ["--xxx", "Bar"] +# ["", "Baz"] +# ["--zzz", ""] +# ["", "Bat"] +# ["", "Bam"] +# Remaining ARGV: [] +# +# === Full Example +# +# File fibonacci.rb: +# +# :include: ../doc/fibonacci.rb +# +# Command line: +# +# $ ruby fibonacci.rb +# +# Output: +# +# Option --number is required. +# Usage: +# +# -n n, --number n: +# Compute Fibonacci number for n. +# -v [boolean], --verbose [boolean]: +# Show intermediate results; default is 'false'. +# -h, --help: +# Show this help. +# +# Command line: +# +# $ ruby fibonacci.rb --number +# +# Raises GetoptLong::MissingArgument: +# +# fibonacci.rb: option `--number' requires an argument +# +# Command line: +# +# $ ruby fibonacci.rb --number 6 +# +# Output: +# +# 8 +# +# Command line: +# +# $ ruby fibonacci.rb --number 6 --verbose +# +# Output: +# 1 +# 2 +# 3 +# 5 +# 8 +# +# Command line: +# +# $ ruby fibonacci.rb --number 6 --verbose yes +# +# Output: +# +# --verbose argument must be true or false +# Usage: +# +# -n n, --number n: +# Compute Fibonacci number for n. +# -v [boolean], --verbose [boolean]: +# Show intermediate results; default is 'false'. # -h, --help: -# show help -# -# --repeat x, -n x: -# repeat x times -# -# --name [name]: -# greet user by name, if name not supplied default is John -# -# DIR: The directory in which to issue the greeting. -# EOF -# when '--repeat' -# repetitions = arg.to_i -# when '--name' -# if arg == '' -# name = 'John' -# else -# name = arg -# end -# end -# end -# -# if ARGV.length != 1 -# puts "Missing dir argument (try --help)" -# exit 0 -# end -# -# dir = ARGV.shift -# -# Dir.chdir(dir) -# for i in (1..repetitions) -# print "Hello" -# if name -# print ", #{name}" -# end -# puts -# end -# -# Example command line: -# -# hello -n 6 --name -- /tmp +# Show this help. # class GetoptLong # Version. @@ -114,20 +398,18 @@ class MissingArgument < Error; end class InvalidOption < Error; end # - # \Set up option processing. - # - # The options to support are passed to new() as an array of arrays. - # Each sub-array contains any number of String option names which carry - # the same meaning, and one of the following flags: + # Returns a new \GetoptLong object based on the given +arguments+. + # See {Options}[#class-GetoptLong-label-Options]. # - # GetoptLong::NO_ARGUMENT :: Option does not take an argument. + # Example: # - # GetoptLong::REQUIRED_ARGUMENT :: Option always takes an argument. + # :include: ../doc/simple.rb # - # GetoptLong::OPTIONAL_ARGUMENT :: Option may or may not take an argument. + # Raises an exception if: # - # The first option name is considered to be the preferred (canonical) name. - # Other than that, the elements of each sub-array can be in any order. + # - Any of +arguments+ is not an array. + # - Any option name or alias is not a string. + # - Any option type is invalid. # def initialize(*arguments) # @@ -189,54 +471,22 @@ def initialize(*arguments) end end + # Sets the ordering; see {Ordering}[#class-GetoptLong-label-Ordering]; + # returns the new ordering. # - # \Set the handling of the ordering of options and arguments. - # A RuntimeError is raised if option processing has already started. - # - # The supplied value must be a member of GetoptLong::ORDERINGS. It alters - # the processing of options as follows: - # - # REQUIRE_ORDER : - # - # Options are required to occur before non-options. - # - # Processing of options ends as soon as a word is encountered that has not - # been preceded by an appropriate option flag. - # - # For example, if -a and -b are options which do not take arguments, - # parsing command line arguments of '-a one -b two' would result in - # 'one', '-b', 'two' being left in ARGV, and only ('-a', '') being - # processed as an option/arg pair. - # - # This is the default ordering, if the environment variable - # POSIXLY_CORRECT is set. (This is for compatibility with GNU getopt_long.) - # - # PERMUTE : - # - # Options can occur anywhere in the command line parsed. This is the - # default behavior. - # - # Every sequence of words which can be interpreted as an option (with or - # without argument) is treated as an option; non-option words are skipped. - # - # For example, if -a does not require an argument and -b optionally takes - # an argument, parsing '-a one -b two three' would result in ('-a','') and - # ('-b', 'two') being processed as option/arg pairs, and 'one','three' - # being left in ARGV. + # If the given +ordering+ is +PERMUTE+ and environment variable + # +POSIXLY_CORRECT+ is defined, sets the ordering to +REQUIRE_ORDER+; + # otherwise sets the ordering to +ordering+: # - # If the ordering is set to PERMUTE but the environment variable - # POSIXLY_CORRECT is set, REQUIRE_ORDER is used instead. This is for - # compatibility with GNU getopt_long. + # options = GetoptLong.new + # options.ordering == GetoptLong::PERMUTE # => true + # options.ordering = GetoptLong::RETURN_IN_ORDER + # options.ordering == GetoptLong::RETURN_IN_ORDER # => true + # ENV['POSIXLY_CORRECT'] = 'true' + # options.ordering = GetoptLong::PERMUTE + # options.ordering == GetoptLong::REQUIRE_ORDER # => true # - # RETURN_IN_ORDER : - # - # All words on the command line are processed as options. Words not - # preceded by a short or long option flag are passed as arguments - # with an option of '' (empty string). - # - # For example, if -a requires an argument but -b does not, a command line - # of '-a one -b two three' would result in option/arg pairs of ('-a', 'one') - # ('-b', ''), ('', 'two'), ('', 'three') being processed. + # Raises an exception if +ordering+ is invalid. # def ordering=(ordering) # @@ -262,14 +512,16 @@ def ordering=(ordering) end # - # Return ordering. + # Returns the ordering setting. # attr_reader :ordering # - # \Set options. Takes the same argument as GetoptLong.new. + # Replaces existing options with those given by +arguments+, + # which have the same form as the arguments to ::new; + # returns +self+. # - # Raises a RuntimeError if option processing has already started. + # Raises an exception if option processing has begun. # def set_options(*arguments) # @@ -341,22 +593,23 @@ def set_options(*arguments) end # - # \Set/Unset `quiet' mode. + # Sets quiet mode and returns the given argument: + # + # - When +false+ or +nil+, error messages are written to $stdout. + # - Otherwise, error messages are not written. # attr_writer :quiet # - # Return the flag of `quiet' mode. + # Returns the quiet mode setting. # attr_reader :quiet - - # - # `quiet?' is an alias of `quiet'. - # alias quiet? quiet # - # Explicitly terminate option processing. + # Terminate option processing; + # returns +nil+ if processing has already terminated; + # otherwise returns +self+. # def terminate return nil if @status == STATUS_TERMINATED @@ -376,7 +629,7 @@ def terminate end # - # Returns true if option processing has terminated, false otherwise. + # Returns +true+ if option processing has terminated, +false+ otherwise. # def terminated? return @status == STATUS_TERMINATED @@ -400,32 +653,25 @@ def set_error(type, message) protected :set_error # - # Examine whether an option processing is failed. + # Returns whether option processing has failed. # attr_reader :error - - # - # `error?' is an alias of `error'. - # alias error? error # Return the appropriate error message in POSIX-defined format. - # If no error has occurred, returns nil. + # If no error has occurred, returns +nil+. # def error_message return @error_message end # - # Get next option name and its argument, as an Array of two elements. - # - # The option name is always converted to the first (preferred) - # name given in the original options to GetoptLong.new. + # Returns the next option as a 2-element array containing: # - # Example: ['--option', 'value'] + # - The option name (the name itself, not an alias). + # - The option value. # - # Returns nil if the processing is complete (as determined by - # STATUS_TERMINATED). + # Returns +nil+ if there are no more options. # def get option_name, option_argument = nil, '' @@ -585,21 +831,32 @@ def get return @canonical_names[option_name], option_argument end + alias get_option get # - # `get_option' is an alias of `get'. + # Calls the given block with each option; + # each option is a 2-element array containing: # - alias get_option get - - # Iterator version of `get'. + # - The option name (the name itself, not an alias). + # - The option value. + # + # Example: + # + # :include: ../doc/each.rb # - # The block is called repeatedly with two arguments: - # The first is the option name. - # The second is the argument which followed it (if any). - # Example: ('--opt', 'value') + # Command line: # - # The option name is always converted to the first (preferred) - # name given in the original options to GetoptLong.new. + # ruby each.rb -xxx Foo -x Bar --yyy Baz -y Bat --zzz + # + # Output: + # + # Original ARGV: ["-xxx", "Foo", "-x", "Bar", "--yyy", "Baz", "-y", "Bat", "--zzz"] + # ["--xxx", "xx"] + # ["--xxx", "Bar"] + # ["--yyy", "Baz"] + # ["--yyy", "Bat"] + # ["--zzz", ""] + # Remaining ARGV: ["Foo"] # def each loop do @@ -608,9 +865,5 @@ def each yield option_name, option_argument end end - - # - # `each_option' is an alias of `each'. - # alias each_option each end From 4666f5b1ca1bdefbb4f9b879fb0e4ad826aa8cc1 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 27 Oct 2021 11:22:19 -0500 Subject: [PATCH 2/5] Respond to olleolleolle review --- lib/getoptlong.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/getoptlong.rb b/lib/getoptlong.rb index c306fca..ceebd64 100644 --- a/lib/getoptlong.rb +++ b/lib/getoptlong.rb @@ -30,14 +30,15 @@ # - Zero or more string aliases for the name. # - An option type. # -# An option may be defined by calling singleton method GetoptLong.new. +# Options may be defined by calling singleton method GetoptLong.new, +# which returns a new \GetoptLong object. # Command-line options may then be processed by calling other methods # such as GetoptLong#each. # # === Option Name and Aliases # # In the array that defines an option, -# the first element is the string the option name. +# the first element is the string option name. # Often the name takes the 'long' form, beginning with two hyphens. # # The option name may have any number of aliases, @@ -129,12 +130,11 @@ # # ==== Option with Required Argument # -# An option of type GetoptLong::REQUIRED_ARGUMENT: +# An option of type GetoptLong::REQUIRED_ARGUMENT # must be followed by an argument, which is associated with that option: # # $ ruby types.rb --xxx foo # -# # Output: # # ["--xxx", "foo"] @@ -155,7 +155,7 @@ # # ==== Option with Optional Argument # -# An option of type GetoptLong::OPTIONAL_ARGUMENT: +# An option of type GetoptLong::OPTIONAL_ARGUMENT # may be followed by an argument, which if given is associated with that option. # # If the option is last, it does not have an argument: @@ -204,7 +204,7 @@ # Before the processing, ARGV includes all words from the command line. # During processing, each found option is removed, along with its argument # if there is one. -# After processing, each remaining element was neither an option +# After processing, each remaining element was neither an option # nor the argument for an option. # # File argv.rb: From 90c768110155711ad4d6285e9c5e5549623bd5e4 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Sun, 7 Nov 2021 16:37:58 -0600 Subject: [PATCH 3/5] Respond to JeremyEvans review --- .gitignore | 1 - doc/getoptlong/abbrev.rb | 9 +++++ doc/getoptlong/aliases.rb | 8 ++++ doc/getoptlong/argv.rb | 12 ++++++ doc/getoptlong/each.rb | 12 ++++++ doc/getoptlong/fibonacci.rb | 62 +++++++++++++++++++++++++++++++ doc/getoptlong/permute.rb | 12 ++++++ doc/getoptlong/require_order.rb | 13 +++++++ doc/getoptlong/return_in_order.rb | 13 +++++++ doc/getoptlong/simple.rb | 7 ++++ doc/getoptlong/types.rb | 10 +++++ lib/getoptlong.rb | 29 ++++++++------- 12 files changed, 173 insertions(+), 15 deletions(-) create mode 100644 doc/getoptlong/abbrev.rb create mode 100644 doc/getoptlong/aliases.rb create mode 100644 doc/getoptlong/argv.rb create mode 100644 doc/getoptlong/each.rb create mode 100644 doc/getoptlong/fibonacci.rb create mode 100644 doc/getoptlong/permute.rb create mode 100644 doc/getoptlong/require_order.rb create mode 100644 doc/getoptlong/return_in_order.rb create mode 100644 doc/getoptlong/simple.rb create mode 100644 doc/getoptlong/types.rb diff --git a/.gitignore b/.gitignore index 4ea5798..ff2a440 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ /.yardoc /_yardoc/ /coverage/ -/doc/ /pkg/ /spec/reports/ /tmp/ diff --git a/doc/getoptlong/abbrev.rb b/doc/getoptlong/abbrev.rb new file mode 100644 index 0000000..9b89863 --- /dev/null +++ b/doc/getoptlong/abbrev.rb @@ -0,0 +1,9 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--xxx', GetoptLong::NO_ARGUMENT], + ['--xyz', GetoptLong::NO_ARGUMENT] +) +options.each do |option, argument| + p [option, argument] +end diff --git a/doc/getoptlong/aliases.rb b/doc/getoptlong/aliases.rb new file mode 100644 index 0000000..895254c --- /dev/null +++ b/doc/getoptlong/aliases.rb @@ -0,0 +1,8 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--xxx', '-x', '--aaa', '-a', '-p', GetoptLong::NO_ARGUMENT] +) +options.each do |option, argument| + p [option, argument] +end diff --git a/doc/getoptlong/argv.rb b/doc/getoptlong/argv.rb new file mode 100644 index 0000000..8efcad2 --- /dev/null +++ b/doc/getoptlong/argv.rb @@ -0,0 +1,12 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--xxx', GetoptLong::REQUIRED_ARGUMENT], + ['--yyy', GetoptLong::OPTIONAL_ARGUMENT], + ['--zzz', GetoptLong::NO_ARGUMENT] +) +puts "Original ARGV: #{ARGV}" +options.each do |option, argument| + p [option, argument] +end +puts "Remaining ARGV: #{ARGV}" diff --git a/doc/getoptlong/each.rb b/doc/getoptlong/each.rb new file mode 100644 index 0000000..661e0a9 --- /dev/null +++ b/doc/getoptlong/each.rb @@ -0,0 +1,12 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--xxx', '-x', GetoptLong::REQUIRED_ARGUMENT], + ['--yyy', '-y', GetoptLong::OPTIONAL_ARGUMENT], + ['--zzz', '-z',GetoptLong::NO_ARGUMENT] +) +puts "Original ARGV: #{ARGV}" +options.each do |option, argument| + p [option, argument] +end +puts "Remaining ARGV: #{ARGV}" diff --git a/doc/getoptlong/fibonacci.rb b/doc/getoptlong/fibonacci.rb new file mode 100644 index 0000000..24a2aab --- /dev/null +++ b/doc/getoptlong/fibonacci.rb @@ -0,0 +1,62 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--number', '-n', GetoptLong::REQUIRED_ARGUMENT], + ['--verbose', '-v', GetoptLong::OPTIONAL_ARGUMENT], + ['--help', '-h', GetoptLong::NO_ARGUMENT] +) + +def help(status = 0) + puts <<~HELP + Usage: + + -n n, --number n: + Compute Fibonacci number for n. + -v [boolean], --verbose [boolean]: + Show intermediate results; default is 'false'. + -h, --help: + Show this help. + HELP + exit(status) +end + +def print_fibonacci (number) + return 0 if number == 0 + return 1 if number == 1 or number == 2 + i = 0 + j = 1 + (2..number).each do + k = i + j + i = j + j = k + puts j if @verbose + end + puts j unless @verbose +end + +options.each do |option, argument| + case option + when '--number' + @number = argument.to_i + when '--verbose' + @verbose = if argument.empty? + true + elsif argument.match(/true/i) + true + elsif argument.match(/false/i) + false + else + puts '--verbose argument must be true or false' + help(255) + end + when '--help' + help + end +end + +unless @number + puts 'Option --number is required.' + help(255) +end + +print_fibonacci(@number) diff --git a/doc/getoptlong/permute.rb b/doc/getoptlong/permute.rb new file mode 100644 index 0000000..8efcad2 --- /dev/null +++ b/doc/getoptlong/permute.rb @@ -0,0 +1,12 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--xxx', GetoptLong::REQUIRED_ARGUMENT], + ['--yyy', GetoptLong::OPTIONAL_ARGUMENT], + ['--zzz', GetoptLong::NO_ARGUMENT] +) +puts "Original ARGV: #{ARGV}" +options.each do |option, argument| + p [option, argument] +end +puts "Remaining ARGV: #{ARGV}" diff --git a/doc/getoptlong/require_order.rb b/doc/getoptlong/require_order.rb new file mode 100644 index 0000000..357f667 --- /dev/null +++ b/doc/getoptlong/require_order.rb @@ -0,0 +1,13 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--xxx', GetoptLong::REQUIRED_ARGUMENT], + ['--yyy', GetoptLong::OPTIONAL_ARGUMENT], + ['--zzz', GetoptLong::NO_ARGUMENT] +) +options.ordering = GetoptLong::REQUIRE_ORDER +puts "Original ARGV: #{ARGV}" +options.each do |option, argument| + p [option, argument] +end +puts "Remaining ARGV: #{ARGV}" diff --git a/doc/getoptlong/return_in_order.rb b/doc/getoptlong/return_in_order.rb new file mode 100644 index 0000000..91ce1ef --- /dev/null +++ b/doc/getoptlong/return_in_order.rb @@ -0,0 +1,13 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--xxx', GetoptLong::REQUIRED_ARGUMENT], + ['--yyy', GetoptLong::OPTIONAL_ARGUMENT], + ['--zzz', GetoptLong::NO_ARGUMENT] +) +options.ordering = GetoptLong::RETURN_IN_ORDER +puts "Original ARGV: #{ARGV}" +options.each do |option, argument| + p [option, argument] +end +puts "Remaining ARGV: #{ARGV}" diff --git a/doc/getoptlong/simple.rb b/doc/getoptlong/simple.rb new file mode 100644 index 0000000..1af6447 --- /dev/null +++ b/doc/getoptlong/simple.rb @@ -0,0 +1,7 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--number', '-n', GetoptLong::REQUIRED_ARGUMENT], + ['--verbose', '-v', GetoptLong::OPTIONAL_ARGUMENT], + ['--help', '-h', GetoptLong::NO_ARGUMENT] +) diff --git a/doc/getoptlong/types.rb b/doc/getoptlong/types.rb new file mode 100644 index 0000000..ac74bfe --- /dev/null +++ b/doc/getoptlong/types.rb @@ -0,0 +1,10 @@ +require 'getoptlong' + +options = GetoptLong.new( + ['--xxx', GetoptLong::REQUIRED_ARGUMENT], + ['--yyy', GetoptLong::OPTIONAL_ARGUMENT], + ['--zzz', GetoptLong::NO_ARGUMENT] +) +options.each do |option, argument| + p [option, argument] +end diff --git a/lib/getoptlong.rb b/lib/getoptlong.rb index ceebd64..d9f3424 100644 --- a/lib/getoptlong.rb +++ b/lib/getoptlong.rb @@ -16,7 +16,7 @@ # # A simple example: file simple.rb: # -# :include: ../doc/simple.rb +# :include: ../doc/getoptlong/simple.rb # # If you are somewhat familiar with command-line options, # you may want to skip to this @@ -51,7 +51,7 @@ # # File aliases.rb: # -# :include: ../doc/aliases.rb +# :include: ../doc/getoptlong/aliases.rb # # On the command line, an option may be cited by its name, # or by any of its aliases; @@ -73,7 +73,7 @@ # # File abbrev.rb: # -# :include: ../doc/abbrev.rb +# :include: ../doc/getoptlong/abbrev.rb # # Command line: # @@ -103,10 +103,11 @@ # ["--xxx", ""] # ["--xyz", ""] # -# === Protected Options +# === Treating Remaining Options as Arguments # -# A command-line option that appears anywhere after the token -- -# is _protected_, and is not processed as an option: +# A option-like token that appears in the command line +# anywhere after the token -- is treated as an ordinary argument, +# and is not processed as an option: # # $ ruby abbrev.rb --xxx --xyz -- --xxx --xyz # @@ -122,7 +123,7 @@ # # File types.rb: # -# :include: ../doc/types.rb +# :include: ../doc/getoptlong/types.rb # # Note that an option type has to do with the option argument # (whether it is required, optional, or forbidden), @@ -209,7 +210,7 @@ # # File argv.rb: # -# :include: ../doc/argv.rb +# :include: ../doc/getoptlong/argv.rb # # Command line: # @@ -242,7 +243,7 @@ # # File permute.rb: # -# :include: ../doc/permute.rb +# :include: ../doc/getoptlong/permute.rb # # Command line: # @@ -265,7 +266,7 @@ # # File require_order.rb: # -# :include: ../doc/require_order.rb +# :include: ../doc/getoptlong/require_order.rb # # Command line: # @@ -286,7 +287,7 @@ # # File return_in_order.rb: # -# :include: ../doc/return_in_order.rb +# :include: ../doc/getoptlong/return_in_order.rb # # Command line: # @@ -307,7 +308,7 @@ # # File fibonacci.rb: # -# :include: ../doc/fibonacci.rb +# :include: ../doc/getoptlong/fibonacci.rb # # Command line: # @@ -403,7 +404,7 @@ class InvalidOption < Error; end # # Example: # - # :include: ../doc/simple.rb + # :include: ../doc/getoptlong/simple.rb # # Raises an exception if: # @@ -842,7 +843,7 @@ def get # # Example: # - # :include: ../doc/each.rb + # :include: ../doc/getoptlong/each.rb # # Command line: # From 1df56738201807a16a0ec399855261bb1c1e5b06 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Mon, 2 May 2022 10:05:59 -0500 Subject: [PATCH 4/5] Enhanced RDoc for GetoptLong --- .gitignore | 1 + {doc => examples}/getoptlong/abbrev.rb | 0 {doc => examples}/getoptlong/aliases.rb | 0 {doc => examples}/getoptlong/argv.rb | 0 {doc => examples}/getoptlong/each.rb | 0 {doc => examples}/getoptlong/fibonacci.rb | 0 {doc => examples}/getoptlong/permute.rb | 0 {doc => examples}/getoptlong/require_order.rb | 0 .../getoptlong/return_in_order.rb | 0 {doc => examples}/getoptlong/simple.rb | 0 {doc => examples}/getoptlong/types.rb | 0 lib/getoptlong.rb | 26 +++++++++---------- 12 files changed, 13 insertions(+), 14 deletions(-) rename {doc => examples}/getoptlong/abbrev.rb (100%) rename {doc => examples}/getoptlong/aliases.rb (100%) rename {doc => examples}/getoptlong/argv.rb (100%) rename {doc => examples}/getoptlong/each.rb (100%) rename {doc => examples}/getoptlong/fibonacci.rb (100%) rename {doc => examples}/getoptlong/permute.rb (100%) rename {doc => examples}/getoptlong/require_order.rb (100%) rename {doc => examples}/getoptlong/return_in_order.rb (100%) rename {doc => examples}/getoptlong/simple.rb (100%) rename {doc => examples}/getoptlong/types.rb (100%) diff --git a/.gitignore b/.gitignore index ff2a440..4ea5798 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /.yardoc /_yardoc/ /coverage/ +/doc/ /pkg/ /spec/reports/ /tmp/ diff --git a/doc/getoptlong/abbrev.rb b/examples/getoptlong/abbrev.rb similarity index 100% rename from doc/getoptlong/abbrev.rb rename to examples/getoptlong/abbrev.rb diff --git a/doc/getoptlong/aliases.rb b/examples/getoptlong/aliases.rb similarity index 100% rename from doc/getoptlong/aliases.rb rename to examples/getoptlong/aliases.rb diff --git a/doc/getoptlong/argv.rb b/examples/getoptlong/argv.rb similarity index 100% rename from doc/getoptlong/argv.rb rename to examples/getoptlong/argv.rb diff --git a/doc/getoptlong/each.rb b/examples/getoptlong/each.rb similarity index 100% rename from doc/getoptlong/each.rb rename to examples/getoptlong/each.rb diff --git a/doc/getoptlong/fibonacci.rb b/examples/getoptlong/fibonacci.rb similarity index 100% rename from doc/getoptlong/fibonacci.rb rename to examples/getoptlong/fibonacci.rb diff --git a/doc/getoptlong/permute.rb b/examples/getoptlong/permute.rb similarity index 100% rename from doc/getoptlong/permute.rb rename to examples/getoptlong/permute.rb diff --git a/doc/getoptlong/require_order.rb b/examples/getoptlong/require_order.rb similarity index 100% rename from doc/getoptlong/require_order.rb rename to examples/getoptlong/require_order.rb diff --git a/doc/getoptlong/return_in_order.rb b/examples/getoptlong/return_in_order.rb similarity index 100% rename from doc/getoptlong/return_in_order.rb rename to examples/getoptlong/return_in_order.rb diff --git a/doc/getoptlong/simple.rb b/examples/getoptlong/simple.rb similarity index 100% rename from doc/getoptlong/simple.rb rename to examples/getoptlong/simple.rb diff --git a/doc/getoptlong/types.rb b/examples/getoptlong/types.rb similarity index 100% rename from doc/getoptlong/types.rb rename to examples/getoptlong/types.rb diff --git a/lib/getoptlong.rb b/lib/getoptlong.rb index d9f3424..4da7b04 100644 --- a/lib/getoptlong.rb +++ b/lib/getoptlong.rb @@ -16,7 +16,7 @@ # # A simple example: file simple.rb: # -# :include: ../doc/getoptlong/simple.rb +# :include: ../examples/getoptlong/simple.rb # # If you are somewhat familiar with command-line options, # you may want to skip to this @@ -51,7 +51,7 @@ # # File aliases.rb: # -# :include: ../doc/getoptlong/aliases.rb +# :include: ../examples/getoptlong/aliases.rb # # On the command line, an option may be cited by its name, # or by any of its aliases; @@ -73,7 +73,7 @@ # # File abbrev.rb: # -# :include: ../doc/getoptlong/abbrev.rb +# :include: ../examples/getoptlong/abbrev.rb # # Command line: # @@ -123,7 +123,7 @@ # # File types.rb: # -# :include: ../doc/getoptlong/types.rb +# :include: ../examples/getoptlong/types.rb # # Note that an option type has to do with the option argument # (whether it is required, optional, or forbidden), @@ -197,9 +197,7 @@ # # === ARGV # -# \GetoptLong does not process the command line itself, -# but instead processes array ARGV (which is derived from the command line). -# This processing is done either with method #each and a block, +# You can process options either with method #each and a block, # or with method #get. # # Before the processing, ARGV includes all words from the command line. @@ -210,7 +208,7 @@ # # File argv.rb: # -# :include: ../doc/getoptlong/argv.rb +# :include: ../examples/getoptlong/argv.rb # # Command line: # @@ -243,7 +241,7 @@ # # File permute.rb: # -# :include: ../doc/getoptlong/permute.rb +# :include: ../examples/getoptlong/permute.rb # # Command line: # @@ -266,7 +264,7 @@ # # File require_order.rb: # -# :include: ../doc/getoptlong/require_order.rb +# :include: ../examples/getoptlong/require_order.rb # # Command line: # @@ -287,7 +285,7 @@ # # File return_in_order.rb: # -# :include: ../doc/getoptlong/return_in_order.rb +# :include: ../examples/getoptlong/return_in_order.rb # # Command line: # @@ -308,7 +306,7 @@ # # File fibonacci.rb: # -# :include: ../doc/getoptlong/fibonacci.rb +# :include: ../examples/getoptlong/fibonacci.rb # # Command line: # @@ -404,7 +402,7 @@ class InvalidOption < Error; end # # Example: # - # :include: ../doc/getoptlong/simple.rb + # :include: ../examples/getoptlong/simple.rb # # Raises an exception if: # @@ -843,7 +841,7 @@ def get # # Example: # - # :include: ../doc/getoptlong/each.rb + # :include: ../examples/getoptlong/each.rb # # Command line: # From d5023fcce9fd26a615f80d10f4dcf395fdc1eae6 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Mon, 2 May 2022 10:31:18 -0500 Subject: [PATCH 5/5] Enhanced RDoc for GetoptLong --- lib/getoptlong.rb | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/getoptlong.rb b/lib/getoptlong.rb index 4da7b04..d07fd95 100644 --- a/lib/getoptlong.rb +++ b/lib/getoptlong.rb @@ -7,10 +7,10 @@ # You may redistribute and/or modify this library under the same license # terms as Ruby. -# \Class \GetoptLong provides command-line parsing both for options +# \Class \GetoptLong provides parsing both for options # and for regular arguments. # -# Using \GetoptLong, you can define command-line options for your program. +# Using \GetoptLong, you can define options for your program. # The program can then capture and respond to whatever options # are included in the command that executes the program. # @@ -18,7 +18,7 @@ # # :include: ../examples/getoptlong/simple.rb # -# If you are somewhat familiar with command-line options, +# If you are somewhat familiar with options, # you may want to skip to this # {full example}[#class-GetoptLong-label-Full+Example]. # @@ -32,7 +32,7 @@ # # Options may be defined by calling singleton method GetoptLong.new, # which returns a new \GetoptLong object. -# Command-line options may then be processed by calling other methods +# Options may then be processed by calling other methods # such as GetoptLong#each. # # === Option Name and Aliases @@ -53,7 +53,7 @@ # # :include: ../examples/getoptlong/aliases.rb # -# On the command line, an option may be cited by its name, +# An option may be cited by its name, # or by any of its aliases; # the parsed option always reports the name, not an alias: # @@ -105,7 +105,7 @@ # # === Treating Remaining Options as Arguments # -# A option-like token that appears in the command line +# A option-like token that appears # anywhere after the token -- is treated as an ordinary argument, # and is not processed as an option: # @@ -119,7 +119,7 @@ # === Option Types # # Each option definition includes an option type, -# which controls whether the option takes an argument on the command line. +# which controls whether the option takes an argument. # # File types.rb: # @@ -200,10 +200,9 @@ # You can process options either with method #each and a block, # or with method #get. # -# Before the processing, ARGV includes all words from the command line. # During processing, each found option is removed, along with its argument # if there is one. -# After processing, each remaining element was neither an option +# After processing, each remaining element was neither an option # nor the argument for an option. # # File argv.rb: @@ -224,8 +223,8 @@ # # === Ordering # -# There are three settings that control the way the command line -# is interpreted: +# There are three settings that control the way the options +# are interpreted: # # - +PERMUTE+. # - +REQUIRE_ORDER+. @@ -236,8 +235,8 @@ # # ==== PERMUTE Ordering # -# In the +PERMUTE+ ordering, command-line options and other, non-option, -# command-line arguments may appear in any order and any mixture. +# In the +PERMUTE+ ordering, options and other, non-option, +# arguments may appear in any order and any mixture. # # File permute.rb: # @@ -259,7 +258,7 @@ # ==== REQUIRE_ORDER Ordering # # In the +REQUIRE_ORDER+ ordering, all options precede all non-options; -# that is, each command-line word after the first non-option word +# that is, each word after the first non-option word # is treated as a non-option word (even if it begins with a hyphen). # # File require_order.rb: @@ -278,7 +277,7 @@ # # ==== RETURN_IN_ORDER Ordering # -# In the +RETURN_IN_ORDER+ ordering, every command-line word is treated as an option. +# In the +RETURN_IN_ORDER+ ordering, every word is treated as an option. # A word that begins with a hyphen (or two) is treated in the usual way; # a word +word+ that does not so begin is treated as an option # whose name is an empty string, and whose value is +word+.