optparse icon indicating copy to clipboard operation
optparse copied to clipboard

Enhance to support 'Set' object as an enum

Open kwatch opened this issue 1 year ago • 3 comments

OptionParser supports Array and Hash object as an enum of option value. But Set object is not supported. For example:

require 'optparse'

parser = OptionParser.new
parser.on("--lang1=<lang>", ["en", "fr", "it"])   # option value will be checked by enum values
parser.on("--lang2=<lang>", Set.new(["en", "fr", "it"]))   # will not be checked when Set object

opts = {}
parser.parse(["--lang2", "ja"], into: opts)   # !!! not raise error !!!
parser.parse(["--lang1", "ja"], into: opts)   # raises error expectedly
p opts

Since Ruby 3.2, Set class is a built-in class. I think that it is very natural for OptionParser to support Set object.

By the way, I can't find a test script to test OptionParser#make_switch() method. Therefore this pull request doesn't contain any test case.

kwatch avatar Oct 03 '24 11:10 kwatch

By the way, I can't find a test script to test OptionParser#make_switch() method. Therefore this pull request doesn't contain any test case.

Added new test script test/optparse/test_switch.rb. If you find something to improve in it, let me know.

kwatch avatar Oct 03 '24 13:10 kwatch

OptionParser supports Array and Hash object as an enum of option value. But Set object is not supported. For example:

parser.on("--lang2=<lang>", Set.new(["en", "fr", "it"]))   # will not be checked when Set object

Array and Hash have literal syntax, but not Set. I can't see the benefit to use Set there. What isn't good with the previous code using an array? Even using the Set also in other places, why not to_a?

lang_set = Set.new(["en", "fr", "it"])
parser.on("--lang2=<lang>", lang_set.to_a)

nobu avatar Mar 10 '25 10:03 nobu

I already explained the reason for OptionParser to support Set object. Quote from the first comment:

Since Ruby 3.2, Set class is a built-in class. I think that it is very natural for OptionParser to support Set object.

The order of elements in enum values for OptionParser is not important. Therefore Set object is appropriate than Array object in this case.

parser.on("--lang1=<lang>", ["en", "fr", "it"])      # orderered?
parser.on("--lang2=<lang>", Set["en", "fr", "it"])   # order not important

In Ruby, it is true that Array object can be used in many cases instead of Set object. But using Set object instad of Array can represent intention of code, and it will help us to write readable and understandable code. Additionally I confirmed by this pull request that the effort to support Set object is very small (just add Set to case-when statement, plus a small test case). Therefore I hope the OptionParser to support the common built-in class.

However, this request arised from philosopy of software and library design rather than from practical benefit of library functionality. If you really do not feel the necessary to support Set object, please reject this request, albeit regrettably.

kwatch avatar Mar 16 '25 15:03 kwatch