non_empty_array 1.0.0 → 1.1.0
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +47 -5
- data/lib/non_empty_array.rb +6 -3
- data/non_empty_array.gemspec +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c54d118eef824c4fffa241971f7c95b927f24597eab6eddc019a434be045160b
|
4
|
+
data.tar.gz: '053186e3e45956d92ee38c4a218228daa881c89c73de2e6b2172762b05283a8c'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8ebda3c33e1bf55e37f2b62bf62a08b1dd7d542fd7017244085084b5c2dc70df2a6cbb79af5f4885ab7a09bdb21637cce6f42e8ee1702be3df07356337e7fef
|
7
|
+
data.tar.gz: 6331e7a5f3e9d9bd9c1210c38e538e457ecd7a228dc2676fd53dff4ab2290425ea9eec7e0723721f77838b9cd8ddacd47170a77b1234b3f7c5820471d7c922be
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,54 @@
|
|
1
|
+
[](https://badge.fury.io/rb/non_empty_array) [](https://travis-ci.com/dogweather/non_empty_array)
|
2
|
+
|
1
3
|
# NonEmptyArray
|
2
4
|
|
3
|
-
An enumerable which is guaranteed to not be empty.
|
5
|
+
An [enumerable](https://ruby-doc.org/core-2.7.1/Enumerable.html) which is guaranteed to not be empty. E.g., `#first`
|
6
|
+
will never fail.
|
4
7
|
|
5
|
-
Additionally,
|
8
|
+
Additionally, three methods which give access:
|
6
9
|
|
7
|
-
* `
|
8
|
-
* `
|
10
|
+
* `#tail`
|
11
|
+
* `#last`
|
12
|
+
* `#all_but_last`
|
9
13
|
|
10
14
|
And one method for mutating the list:
|
11
15
|
|
12
|
-
*
|
16
|
+
* `#push`
|
17
|
+
|
18
|
+
## Why is this useful?
|
19
|
+
|
20
|
+
Sometimes I know that an Array isn't empty. In fact, it should never be empty, because
|
21
|
+
otherwise, it means the object was set up incorrectly. The usual way to handle this is
|
22
|
+
to check the array's length, or check for nil, and throw an exception if, for some
|
23
|
+
reason, the Array _is_ empty.
|
24
|
+
|
25
|
+
This `NonEmptyArray` approach saves this unnecessary work by moving the non-emptyness
|
26
|
+
into the type system, letting Ruby check and prevent misuse. I.e., this class is
|
27
|
+
designed so that it's impossible for it to be empty. And it has accessors like `#last`
|
28
|
+
which always returns an element - it can never fail:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'non_empty_array'
|
32
|
+
|
33
|
+
a = NonEmptyArray.new() # => Ruby error - missing parameter
|
34
|
+
```
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
require 'non_empty_array'
|
38
|
+
|
39
|
+
a = NonEmptyArray.new(100, [200, 300])
|
40
|
+
|
41
|
+
# Methods from Enumerable
|
42
|
+
a.count() # => 3
|
43
|
+
a.max() # => 300
|
44
|
+
a.to_a() # => [100, 200, 300]
|
45
|
+
|
46
|
+
# Methods specific to NonEmptyArray
|
47
|
+
a.last() # => 300 Always succeeds - never returns a "no element" error.
|
48
|
+
a.all_but_last() # => [100, 200] A normal array, which may indeed be empty.
|
49
|
+
a.push('400')
|
50
|
+
a.all_but_last() # => [100, 200, 300]
|
51
|
+
a.tail() # => [200, 300, 400]
|
52
|
+
```
|
53
|
+
|
54
|
+
Influenced by [Haskell's NonEmpty List](https://hackage.haskell.org/package/base-4.14.0.0/docs/Data-List-NonEmpty.html).
|
data/lib/non_empty_array.rb
CHANGED
@@ -18,7 +18,7 @@ class NonEmptyArray
|
|
18
18
|
|
19
19
|
sig { override.params(block: T.untyped).void }
|
20
20
|
def each(&block)
|
21
|
-
|
21
|
+
all_elements.each(&block)
|
22
22
|
end
|
23
23
|
|
24
24
|
sig { returns(T.untyped) }
|
@@ -28,9 +28,12 @@ class NonEmptyArray
|
|
28
28
|
|
29
29
|
sig { returns(T::Array[T.untyped]) }
|
30
30
|
def all_but_last
|
31
|
-
T.must(
|
31
|
+
T.must(all_elements.slice(0..-2))
|
32
32
|
end
|
33
33
|
|
34
|
+
sig { returns(T::Array[T.untyped]) }
|
35
|
+
attr_reader :tail
|
36
|
+
|
34
37
|
sig { params(element: T.untyped).returns(NonEmptyArray) }
|
35
38
|
def push(element)
|
36
39
|
@tail.push(element)
|
@@ -40,7 +43,7 @@ class NonEmptyArray
|
|
40
43
|
private
|
41
44
|
|
42
45
|
sig { returns(T::Array[T.untyped]) }
|
43
|
-
def
|
46
|
+
def all_elements
|
44
47
|
[@head] + @tail
|
45
48
|
end
|
46
49
|
end
|
data/non_empty_array.gemspec
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'non_empty_array'
|
5
|
-
spec.version = '1.
|
5
|
+
spec.version = '1.1.0'
|
6
6
|
spec.authors = ['Robb Shecter']
|
7
7
|
spec.email = ['robb@public.law']
|
8
8
|
|
9
9
|
spec.summary = 'An ordered list guaranteed to have at least one element.'
|
10
|
-
spec.description = "Inspired by Haskell's
|
10
|
+
spec.description = "Inspired by Haskell's NonEmpty list"
|
11
11
|
spec.homepage = 'https://github.com/dogweather/non_empty_array'
|
12
12
|
spec.license = 'MIT'
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: non_empty_array
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robb Shecter
|
@@ -38,7 +38,7 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.5.5890
|
41
|
-
description: Inspired by Haskell's
|
41
|
+
description: Inspired by Haskell's NonEmpty list
|
42
42
|
email:
|
43
43
|
- robb@public.law
|
44
44
|
executables: []
|