Skip to content

Commit

Permalink
Argument / Option Value Container
Browse files Browse the repository at this point in the history
  • Loading branch information
mosop committed Nov 13, 2016
1 parent dfa65b4 commit 4929b03
Show file tree
Hide file tree
Showing 60 changed files with 682 additions and 218 deletions.
297 changes: 294 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ result = Model.parse(%w(foo -s string bar -b baz))
result.args # => ["foo", "bar", "baz"]
```

### Named Argument
### Named Arguments

```crystal
class Model < Optarg::Model
Expand All @@ -140,8 +140,8 @@ result = Model.parse(%w(/path/to/src /path/to/build and more))
result.args.src_dir # => "/path/to/src"
result.args.build_dir # => "/path/to/build"
result.args # => ["/path/to/src", "/path/to/build", "and", "more"]
result.args.named # => {"src_dir" => "/path/to/src", "build_dir" => "/path/to/build"}
result.args.nameless # => ["and", "more"]
result.named_args # => {"src_dir" => "/path/to/src", "build_dir" => "/path/to/build"}
result.nameless_args # => ["and", "more"]
```

### Inheritance (Reusable Model)
Expand Down Expand Up @@ -260,8 +260,299 @@ require "optarg"

and see [Features](#features).

## Accessing Parsed Values

### Value Container

A value container is an object for storing parsed values. A value container is one of the following types:

* [Argument Value Container](#argument_value_container)
* [Option Value Container](#option_value_container)
* [Named Argument Value Hash](#named_argument_value_hash)
* [Nameless Argument Value Array](#nameless_argument_value_array)
* [Parsed Argument Value Array](#parsed_argument_value_array)
* [Unparsed Argument Value Array](#unparsed_argument_value_array)

#### Argument Value Container

<a name="argument_value_container"></a>

An argument value container is an Array-like object that contains argument values of a model object.

To access argument value containers, use the `Optarg::Model#args` method.

```crystal
class Model < Optarg::Model
end
result = Model.parse(%w(foo bar baz))
result.args.size # => 3
result.args[0] # => "foo"
result.args[1] # => "bar"
result.args[2] # => "baz"
result.args.map{|i| "#{i}!"} # => ["foo!", "bar!", "baz!"]
```

#### Option Value Container

<a name="option_value_contianer"></a>

An option value container is a set of Hash objects that contains option values of a model object.

Every option value container has 3 hashes. Each hash is one of the following types:

* String
* Bool
* Array(String)

To access option value container, use the `Optarg::Model#options` method.

To access the hashes, use the option value container's `#[]` method with a target type.

```crystal
class Model < Optarg::Model
string "-s"
bool "-b"
array "-a"
end
result = Model.parse(%w(-s foo -b -a bar -a baz))
result.options[String] # => {"-s" => "foo"}
result.options[Bool] # => {"-b" => true}
result.options[Array(String)] # => {"-a" => ["bar", "baz"]}
```

##### Key for Multiple Names

If an option has multiple names, only the first name can be used as a hash key.

```crystal
class Model < Optarg::Model
bool %w(-f --force)
end
result = Model.parse(%w(--force))
result.options[Bool]["-f"] # => true
result.options[Bool]["--force"] # raises KeyError
```

#### Named Argument Value Hash

<a name="named_argument_value_hash"></a>

A named argument value hash is an Hash object that contains named argument values of a model object.

To access named argument value hashes, use the `Optarg::Model#named_args` method.

```crystal
class Model < Optarg::Model
arg "named"
end
result = Model.parse(%w(foo bar baz))
result.named_args # => {"named" => "foo"}
```

#### Nameless Argument Value Array

<a name="nameless_argument_value_array"></a>

A nameless argument value array is an Array object that contains nameless argument values of a model object.

To access nameless argument value arrays, use the `Optarg::Model#nameless_args` method.

```crystal
class Model < Optarg::Model
arg "named"
end
result = Model.parse(%w(foo bar baz))
result.nameless_args # => ["bar", "baz"]
```

#### Parsed Argument Value Array

<a name="parsed_argument_value_array"></a>

A parsed argument value array is an Array object that contains parsed argument values of a model object, regardless of named or nameless.

To access parsed argument value arrays, use the `Optarg::Model#parsed_args` method.

```crystal
class Model < Optarg::Model
arg "named"
end
result = Model.parse(%w(foo bar baz))
result.parsed_args # => ["foo", "bar", "baz"]
```

Parsed argument value arrays are very similar to argument value containers in enumeration functionality. They are different in that an argument value container is an Array-like object and provides value accessors, whereas a parsed argument value array is just an Array object.

#### Unparsed Argument Value Array

<a name="unparsed_argument_value_array"></a>

An unparsed argument value array is an Array object that contains unparsed argument values of a model object.

To access unparsed argument value arrays, use the `Optarg::Model#unparsed_args` method.

```crystal
class Model < Optarg::Model
arg "stopper", stop: true
end
result = Model.parse(%w(foo bar baz))
result.unparsed_args # => ["bar", "baz"]
```

### Value Accessor

A value accessor is a method to get a named value. A named value is a value of either an option or a named argument.

Value accessors are automatically defined in model objects and value containers.

The name of a value accessor is determined by the name of a corresponding option or argument. Any leading dash signs (`-`) are eliminated and the other dashes are converted to underscore letters (`_`). For example, `--option-name` is converted to `option_name`.

A value accessor is one of the following types:

* [String Option Value Accessor](#string_option_value_accessor)
* [Bool Option Value Accessor](#bool_option_value_accessor)
* [String-Array Option Value Accessor](#string-array_option_value_accessor)
* [Named Argument Value Accessor](#named_argument_value_accessor)

#### String Option Value Accessor

<a name="string_option_value_accessor"></a>

A string option value accessor is a method to get a string option's value.

For a string option, a nillable value accessor is also defined. If a value is not set, the nillable value accessor returns nil instead raises an exception. The name of a nillable value accessor has a trailing `?` character.

String option value accessors are defined in model objects and option value containers.

```crystal
class Model < Optarg::Model
string "-s"
end
result = Model.parse(%w(-s value))
result.s # => "value"
result.options.s # equivalent to result.s
not_set = Model.parse(%w())
not_set.s # raises KeyError
not_set.s? # => nil
not_set.options.s # equivalent to not_set.s
not_set.options.s? # equivalent to not_set.s?
```

#### Bool Option Value Accessor

<a name="bool_option_value_accessor"></a>

A bool option value accessor is a method to get a bool option's value.

The name of a bool option value accessor has a trailing `?` character.

If a value is not set, a bool option value accessor returns false.

Bool option value accessors are defined in model objects and option value containers.

```crystal
class Model < Optarg::Model
bool "-b"
end
result = Model.parse(%w(-b))
result.b? # => true
result.options.b? # equivalent to result.b?
not_set = Model.parse(%w())
not_set.b? # => false
not_set.options.b? # equivalent to not_set.b?
```

#### String-Array Option Value Accessor

<a name="string-array_option_value_accessor"></a>

A string-array option value accessor is a method to get an string-array option's value.

String-Array option value accessors are defined in model objects and option value containers.

```crystal
class Model < Optarg::Model
array "-a"
end
result = Model.parse(%w(-a foo -a bar -a baz))
result.a # => ["foo", "bar", "baz"]
result.options.a # equivalent to result.a
```

#### Named Argument Value Accessor

<a name="named_argument_value_accessor"></a>

A named argument value accessor is a method to get a named argument's value.

For a named argument, a nillable value accessor is also defined. If a value is not set, the nillable value accessor returns nil instead raises an exception. The name of a nillable value accessor has a trailing `?` character.

Named argument value accessors are defined in model objects and argument value containers.

```crystal
class Model < Optarg::Model
arg "arg1"
arg "arg2"
end
result = Model.parse(%w(foo bar))
result.arg1 # => "foo"
result.arg2 # => "bar"
result.args.arg1 # equivalent to result.arg1
result.args.arg2 # equivalent to result.arg2
```

#### Avoiding Overriding Methods

If an accessor's name is used for any methods that are already defined, the accessor won't be defined and the predefined method won't be overridden.

For model objects (`Optarg::Model`), all the methods of its ancestor classes (`Reference` and `Object`) and the following methods are not overridden:

* args
* named_args
* nameless_args
* options
* parse
* parsed_args
* parser
* unparsed_args

For argument value container objects (`Optarg::ArgumentValueContainer`) and option value container objects (`Optarg::OptionValueContainer`), all the methods of its ancestor classes (`Reference` and `Object`) are not overridden.

```crystal
class Model < Optarg::Model
string "--class"
end
result = Model.parse(%w(--class foo))
result.class # => Model
result.options[String]["--class"] # => "foo"
```

## Want to Do

* Validation
* Inclusion
* Custom Handler

## Release Notes

* v0.4.0
* (Breaking Change) Removed Model#args.named Model#args.nameless. Use Model#named_args, Model#nameless_args instead.
* Argument Value Container
* Option Value Container
* v0.3.0
* Stop and Termination
* (Breaking Change) "--" (double dash) is no longer a special argument by default. Use the `Model.terminator` method.
Expand Down
17 changes: 17 additions & 0 deletions spec/classes/argument_value_container_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require "../spec_helper"

module OptargArgumentValueContainerClassFeature
class Model < Optarg::Model
end

it "#[]" do
list = Model::ArgumentValueContainer.new
list.__values << "arg"
list[0].should eq "arg"
end

it "#[]?" do
list = Model::ArgumentValueContainer.new
list[0]?.should be_nil
end
end
17 changes: 0 additions & 17 deletions spec/classes/argument_value_list_spec.cr

This file was deleted.

13 changes: 13 additions & 0 deletions spec/classes/option_value_container_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require "../spec_helper"

module OptargOptionValueContainerClassFeature
class Model < Optarg::Model
end

it "#[]" do
list = Model::OptionValueContainer.new
list[String].class.should eq Hash(String, String?)
list[Bool].class.should eq Hash(String, Bool?)
list[Array(String)].class.should eq Hash(String, Array(String))
end
end
10 changes: 4 additions & 6 deletions spec/features/accessor_spec.cr
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
require "../spec_helper"

module Optarg::AccessorFeature
class Model < ::Optarg::Model
module OptargAccessorFeature
class Model < Optarg::Model
string "--foo"
end
end

describe "Accessor" do
it "" do
result = Optarg::AccessorFeature::Model.parse(%w(--foo bar))
it name do
result = Model.parse(%w(--foo bar))
result.foo.should eq "bar"
end
end
2 changes: 1 addition & 1 deletion spec/features/arguments_spec.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "../spec_helper"

module OptargArgumentsFeature
class Model < ::Optarg::Model
class Model < Optarg::Model
string "-s"
bool "-b"
end
Expand Down
Loading

0 comments on commit 4929b03

Please sign in to comment.