clamp icon indicating copy to clipboard operation
clamp copied to clipboard

Add `:allowed` option for attributes

Open AlexWayfer opened this issue 3 years ago • 4 comments

To check if a given value included in pre-defined list.

AlexWayfer avatar Jun 25 '22 16:06 AlexWayfer

Sorry Alex, but I'm not convinced there's a strong need for this new :allowed option. What are the advantages over just using a validation block?

mdub avatar Jul 14 '22 10:07 mdub

Sorry Alex, but I'm not convinced there's a strong need for this new :allowed option. What are the advantages over just using a validation block?

Just an easier option with unification (determined error). Also it'll make easier to define dynamic values for CLIs. For example, I'm developing CLI tools for projects generations via templates, and different templates can have different options with a strict list of allowed values. Oh, I've remembered: answering to your question, this option (I mean, all allowed values) also will be displayed in the help, I don't imagine how to do this with regular block validation, only in the error message.

AlexWayfer avatar Jul 14 '22 11:07 AlexWayfer

Mmm, I get that a validation block doesn't magically extend the help text, but it's not that hard, e.g.

SIZES = %w(S M L XL)

option "--size", "SIZE", "T-shirt size (#{SIZES.join("/")})" do |arg|
  raise ArgumentError, "invalid size" unless SIZES.include?(arg)
end

I just worry that adding sugar for one particular type of argument validation (membership of a list) is a slippery slope, i.e. it sets a precedent, encouraging people to think Clamp should have explicit support for other types of validation, too (e.g. range checks).

I wonder if a better approach might be to support "validator" objects for options/parameters, kind of like I did in config_mapper (see "Type validation/coercion"). A validator object could have the following interface:

  • validator.call(arg) to validate/coerce a String argument
  • validator.to_s to self-describe the "type", for inclusion in help

mdub avatar Jul 14 '22 11:07 mdub

@mdub maybe you're right. And it's your projects, you decide. But, the reason why I've chosen Ruby over Python, for example, it's the variety of aliases and possibilities. Python says to you "don't use exit, use quit", Ruby says "exit? OK, I got you" and do exactly what you want.

I think this is a common case, as well as ranges validation which you've mentioned. I don't see a problem in such features. Also I've got your opinion about validation classes, and it's not bad, but it'll make such simple validations more complicated (new class definition, usage, etc.)

But it's up to you.

AlexWayfer avatar Jul 23 '22 16:07 AlexWayfer

Just to chime in here, I've built many gems that use CLI interface, and I too feel that :allowed is a weird validator. I think that supporting arbitrary validators via Validator type classes would be a much more flexible and extensible solution.

kigster avatar Sep 13 '22 23:09 kigster

I do like the idea of a more general solution, with "validator" or "type" objects, though. I figure usage might look something like:

option "--size", "SIZE", "T-shirt size", type: one_of(%w(S M L XL))

I imagine a library of "type constructors", e.g. one_of(), range(), etc? It feels general enough that it could be separate from Clamp itself.

I might have a go at implementing something like that, in a free moment. Or, I might not, so would be happy for something else to have a crack at it.

In the meantime, I'm going to say "thanks but no thanks" on this one, @AlexWayfer.

mdub avatar Sep 17 '22 00:09 mdub