errgonomic 0.10.1 → 0.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 543390fc5f85546ffde4785cfc41951400800094506078271cfe32535e9d784a
4
- data.tar.gz: 8d5cdf061dbf7026eaab5ba8cab628368c600943699dbad04235c9d1d9bd3f5a
3
+ metadata.gz: 94eb90cd1a2a6e07d42a5bc9318fc34cea84cff058c6d78299c2aa1673279b3e
4
+ data.tar.gz: c8516b096821a7a1902805687a51b7f07f1443adeccf50f3b85659006f431b61
5
5
  SHA512:
6
- metadata.gz: ad7cbe42d7f1d65549323c026a3f4486d4e64a9b5274023fc3eebb0a576ceb09c030151d176512220e13ef8d6e1bc3c2bff78162783ecb286bbb6805ac16c8c9
7
- data.tar.gz: 4588909f84b800a1c497882d030fd88f23606146fe64b7ae02ecc8b7f4406ba2c5dd749d0c709c7004717de80a9a69e73d6247b2ce11013446fa25db66271c3d
6
+ metadata.gz: 4a3803504c4789e6bf2df90f28348e90f72089121e2a2b06f2ba8ec28db7082286447ff07ca6c2c23cd5a41e38d86e31b454237ae3d2299ed4d1f97d0b57518a
7
+ data.tar.gz: c868b2d29da869091801aac2b5295b5a69a67ac405a9a14d38e62021048ff5133dfd288d61caadbfb783f512da3cd409fda19453c55a13610a8525af6a2b46fb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.11.0] - 2026-09-16
4
+
5
+ This release makes a converted model's query methods and a delegated predicate answer the verdict a boolean caller asked for, rather than something an `if` reads as true.
6
+
7
+ ### Upgrading from 0.10.2
8
+
9
+ An application that prepended its own `query_attribute` unwrap to work around a wrapped column's `attr?` answering true for `false`, `0` or `""` can delete it: the concern does it now, and a prepended copy is redundant rather than harmful. A `delegate_optional` whose method name ends in `?` returns `true` or `false` where it returned an Option, so `some?`, `unwrap_or` and the other combinators on that result are a `NoMethodError`. Read the boolean instead. The one loss is a `?` method that answers a value by design, which now answers `true`: declare it without the `?`, or write `some_and?` by hand. The seam to watch is `Object#to_option`, which lifts whatever it is handed, so `record.delegated?.to_option` is `Some(false)` for an absent target where it was `None`.
10
+
11
+ ### Changes
12
+
13
+ - [Bug fix] A converted model's `query_attribute`, its private `attribute?` alias and the `attr?` methods Rails generates from them answer what the unconverted model answers for a wrapped column, so `note.pinned?` is `false` for an explicit `false` and `note.rank?` is `false` for a `0`. The concern overrides `query_attribute` to unwrap the reader's Option before handing the value to Rails' own cast. Previously the cast saw a `Some`, missed its `true` and `false, nil` arms and fell through to `!blank?`, where `Option#blank?` is `none?`, so every present value answered true ([#88](https://github.com/omc/errgonomic/issues/88))
14
+ - [Behavior change] `delegate_optional` with a method name ending in `?` answers `true` or `false` through `some_and?`, reading an absent target as `false`, where it answered `Some(true)`, `Some(false)` and `None` before. A `?` name asks for a verdict and no Option can serve as one, because every Option is truthy: `Some(false)` and `None` both took the true branch of an `if`, which is the silent wrong branch that `delegate ..., allow_nil: true` does not have. Every other name is lifted into an Option as before, and there is no opt-out keyword ([#89](https://github.com/omc/errgonomic/issues/89))
15
+
16
+ ## [0.10.2] - 2026-09-10
17
+
18
+ This release makes every `Err` carry an error and removes `Option#ok`, the one method that built an `Err` without one.
19
+
20
+ ### Upgrading from 0.10.1
21
+
22
+ Replace `Err()` with `Err(reason)`, and a pattern `in Err()` with `in Err` or `in Err(_)`: `Err()` and `Errgonomic::Result::Err.new` with no argument raise `ArgumentError`, and `in Err()` no longer matches any `Err`. Replace `opt.ok` with `opt.ok_or(reason)`; `ok` on an Option now raises `Errgonomic::UnwrappedAccessError`, which names `ok_or` and `ok_or_else`.
23
+
24
+ ### Changes
25
+
26
+ - [Behavior change] `Err()` and `Errgonomic::Result::Err.new` with no argument raise `ArgumentError`. A value-less `Err` held an internal placeholder, `Errgonomic::Result::Err::Arbitrary`, which `unwrap_err!` handed back to the caller, a gem-internal value leaking into application data. The placeholder is deleted along with the special case that made `Err().deconstruct` answer `[]`, so `Err(e).deconstruct` is always `[e]`, `in Err(e)` and `in Err(_)` match every `Err`, and `in Err()` matches none. `Err(nil)` is unchanged: it carries `nil`
27
+ - `Option#ok` is removed. `None().ok` was the only method that returned a value-less `Err`, and Rust has no `Option::ok`; `ok_or` and `ok_or_else` make the caller name the error
28
+ - [Docs] The README's Known limitations section names a converted model's `belongs_to ..., optional: true, touch: true`, which raises `Errgonomic::UnwrappedAccessError` on a save or a destroy with the association absent because a `None` does not delegate `persisted?`, and gives `errgonomic_optional_except` as the way around it. The limitation predates 0.10.2
29
+
3
30
  ## [0.10.1] - 2026-09-10
4
31
 
5
32
  This release makes cross-type equality raise unconditionally and removes the switch that used to turn it on.
data/README.md CHANGED
@@ -403,7 +403,7 @@ The declaration reads as well above the include as below it, as `errgonomic_opti
403
403
 
404
404
  `Model.errgonomic_optionals` reports which readers a model wrapped, including nullable foreign-key columns, so `book.author_id` is `Some(1)` alongside `book.author`. That is how to check that a conversion did what it meant to. A subclass reports what it inherited alongside anything it wrapped itself, so the report names every wrapped reader the class responds to; `Model.errgonomic_optional_names` is the set that class wrapped on its own.
405
405
 
406
- `delegate_optional` is Rails' `delegate` with `allow_nil`, where the absent case is a `None` rather than a `nil`: `delegate_optional :name, to: :author` gives `book.name # => Some('Cixin Liu')`, and `None()` where there is no author. The prefix forms are Rails': `prefix: true` names the reader after the target (`author_name`), and `prefix: :writer` names it `writer_name`. `private: true` works as it does there. The reader forwards whatever it was called with, arguments and block alike. `allow_nil: true` is accepted and says nothing new, so a `delegate` declaration swaps over unchanged unless it delegates a writer. `delegate_optional :name=, to: :author` raises instead: an assignment through an absent target has nowhere to put the value, and dropping it silently is what the type is there to prevent. `allow_nil: false` asks for a reader that raises on absence, which this does not have, so it raises `ArgumentError` where it is written, as a declaration with no `to:` does.
406
+ `delegate_optional` is Rails' `delegate` with `allow_nil`, where the absent case is a `None` rather than a `nil`: `delegate_optional :name, to: :author` gives `book.name # => Some('Cixin Liu')`, and `None()` where there is no author. The prefix forms are Rails': `prefix: true` names the reader after the target (`author_name`), and `prefix: :writer` names it `writer_name`. `private: true` works as it does there. The reader forwards whatever it was called with, arguments and block alike. `allow_nil: true` is accepted and says nothing new, so a `delegate` declaration swaps over unchanged unless it delegates a writer or a predicate. A name ending in `?` asks for a verdict, and no Option can serve as one, because every Option is truthy. So a predicate answers a bare `true` or `false` through `some_and?`: `delegate_optional :prolific?, to: :author` gives `book.prolific? # => false` for an unprolific author, and `false` again where there is no author, which branches an `if` the way Rails' `allow_nil: true` does. The one thing that costs is a `?` method that answers a value by design, which now answers `true`; declare it without the `?`, or write `some_and?` by hand. `delegate_optional :name=, to: :author` raises instead: an assignment through an absent target has nowhere to put the value, and dropping it silently is what the type is there to prevent. `allow_nil: false` asks for a reader that raises on absence, which this does not have, so it raises `ArgumentError` where it is written, as a declaration with no `to:` does.
407
407
 
408
408
  It is available on every model, converted or not, because it lifts both ends one layer. The target is lifted, so a plain record reads as `Some` and a `nil` as `None`. What the delegated call returns is lifted too, so a delegated reader that is itself an Option comes back as one Option rather than two.
409
409
 
@@ -423,6 +423,10 @@ This is the register of where the gem leaves the Rust idiom, and why. ActiveReco
423
423
 
424
424
  The set is closed. If a future integration appears to need a sixth compromise, that is a signal ActiveRecord is pushing back somewhere unmapped, and it warrants a design discussion rather than a quiet patch. `errgonomic_optional_except` and `errgonomic_serialize_none` are deliberately not on the list: they are configuration, an escape hatch that softens the all-or-nothing include for whatever conflict shows up next and a choice of how an absent value is written, rather than semantic exceptions.
425
425
 
426
+ #### Known limitations
427
+
428
+ A converted model with `belongs_to :writer, optional: true, touch: true` raises `Errgonomic::UnwrappedAccessError` (``undefined method `persisted?' for None``) when it saves or is destroyed with the association absent: on `create`, on any `update`, and on `destroy`. ActiveRecord's touch callback reads the association back through the public reader and asks `record && record.persisted?`, and a `None` is truthy and does not delegate `persisted?` the way a `Some` does. Leave the association unwrapped with `errgonomic_optional_except :writer`, which keeps `touch: true` working and hands back `nil` for an absent record.
429
+
426
430
  ## Development
427
431
 
428
432
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment. The repository is a self-contained Nix flake; with direnv, `direnv allow` puts the right toolchain on your path.
data/doctest_helper.rb CHANGED
@@ -76,6 +76,10 @@ class Writer < ActiveRecord::Base
76
76
  def styled_name
77
77
  yield(name)
78
78
  end
79
+
80
+ def credited?
81
+ !bio.nil?
82
+ end
79
83
  end
80
84
 
81
85
  # A converted model reads its association as an Option.
@@ -86,6 +90,7 @@ class Article < ActiveRecord::Base
86
90
  delegate_optional :name, to: :writer, prefix: :author
87
91
  delegate_optional :bio, to: :writer
88
92
  delegate_optional :greeting, :styled_name, to: :writer, prefix: true
93
+ delegate_optional :credited?, to: :writer
89
94
  delegate_optional :table_name, to: :class
90
95
  end
91
96
 
@@ -626,21 +626,24 @@ module Errgonomic
626
626
  block.call(value)
627
627
  end
628
628
 
629
- # convert the option into a result where Some is Ok and None is Err
630
- # @example
631
- # None().ok # => Err()
632
- # Some(1).ok # => Ok(1)
633
- def ok
634
- return Errgonomic::Result::Ok.new(value) if some?
635
-
636
- Errgonomic::Result::Err.new
637
- end
638
-
639
629
  # Transforms the option into a result, mapping Some(v) to Ok(v) and None to Err(err)
640
630
  #
641
631
  # @example
642
632
  # None().ok_or("wow") # => Err("wow")
643
633
  # Some(1).ok_or("such err") # => Ok(1)
634
+ #
635
+ # @example there is no bare ok: an Err always names its error
636
+ # begin
637
+ # None().ok
638
+ # rescue NoMethodError => e
639
+ # e.class
640
+ # end # => Errgonomic::UnwrappedAccessError
641
+ # begin
642
+ # Some(1).ok
643
+ # rescue NoMethodError => e
644
+ # e.class
645
+ # end # => Errgonomic::UnwrappedAccessError
646
+ # Some(1).respond_to?(:ok) # => false
644
647
  def ok_or(err)
645
648
  return Errgonomic::Result::Ok.new(value) if some?
646
649
 
@@ -27,6 +27,11 @@ module Errgonomic
27
27
  # @!method delegate_optional(*methods, to: nil, prefix: nil, private: nil, allow_nil: nil)
28
28
  # @!scope class
29
29
  # Delegates to an optional target, answering an Option: None where the target is absent.
30
+ # A name ending in `?` is the exception: it answers a bare boolean, false for an absent target.
31
+ # @example a predicate answers a verdict rather than an Option, since every Option is truthy
32
+ # Article.create!(title: 'Omelas', writer: Writer.create!(name: 'Ursula', bio: 'writes')).credited? # => true
33
+ # Article.create!(title: 'Omelas', writer: Writer.create!(name: 'Ursula')).credited? # => false
34
+ # Article.create!(title: 'Untitled').credited? # => false
30
35
  # @example prefix forms name the reader, as they do for Rails' delegate
31
36
  # article = Article.create!(title: 'Omelas', writer: Writer.create!(name: 'Ursula', bio: 'writes'))
32
37
  # article.writer_name # => Some('Ursula')
@@ -158,11 +163,25 @@ module Errgonomic
158
163
  def define_optional_delegation(receiver, method_name, reader, declared_at)
159
164
  class_eval <<-RUBY, declared_at.path, declared_at.lineno # rubocop:disable Style/EvalWithLocation
160
165
  def #{reader}(...)
161
- #{receiver}.to_option.and_then { |target| target.#{method_name}(...).to_option }
166
+ #{delegation_body(receiver, method_name)}
162
167
  end
163
168
  RUBY
164
169
  end
165
170
 
171
+ # A ? name asks for a verdict, and an Option is not usable as one:
172
+ # every Option is truthy, so Some(false) and None both take the true
173
+ # branch. A predicate therefore answers a bare boolean, reading an
174
+ # absent target as false, which branches the way nil does.
175
+ def delegation_body(receiver, method_name)
176
+ return "#{receiver}.to_option.some_and? { |target| target.#{method_name}(...) }" if predicate?(method_name)
177
+
178
+ "#{receiver}.to_option.and_then { |target| target.#{method_name}(...).to_option }"
179
+ end
180
+
181
+ def predicate?(method_name)
182
+ method_name.to_s.end_with?('?')
183
+ end
184
+
166
185
  # A target named for a Ruby keyword reads as the keyword in the body
167
186
  # it is written into, so it needs an explicit receiver. Rails answers
168
187
  # the same question for delegate, and answers it for the same names.
@@ -38,10 +38,12 @@ module Errgonomic
38
38
  # Validation unwraps at read_attribute_for_validation, the seam every
39
39
  # EachValidator fetches an attribute through; serialization at
40
40
  # read_attribute_for_serialization, the seam every attribute in a
41
- # payload is fetched through; and a form helper at ActionView's tag
42
- # value, the seam every field reads its record through. So a standard
43
- # validator weighs the value, a payload carries it and a form renders
44
- # it, rather than the wrapper. A singular association with nested
41
+ # payload is fetched through; a form helper at ActionView's tag
42
+ # value, the seam every field reads its record through; and a query
43
+ # method at query_attribute, the seam every generated attr? is cast
44
+ # through. So a standard validator weighs the value, a payload carries
45
+ # it, a form renders it and a query method answers for it, rather than
46
+ # for the wrapper. A singular association with nested
45
47
  # attributes goes further and keeps its plain reader: nested attributes
46
48
  # are assigned through the reader, and ActiveRecord asks whatever it
47
49
  # finds there whether it is a new record. So does a reader a framework
@@ -115,6 +117,29 @@ module Errgonomic
115
117
  errgonomic_omit_absent_keys(hash)
116
118
  end
117
119
 
120
+ # A query method reads the record through the public reader and matches
121
+ # what it finds against true, then false and nil, before falling through
122
+ # to blankness. An Option is none of those, and its blankness is its
123
+ # discriminant rather than its value, so an explicit false and a stored
124
+ # zero would answer true. Unwrapping the read is what keeps the answer
125
+ # the one an unconverted model gives.
126
+ #
127
+ # @example
128
+ # Note.new(pinned: false).pinned? # => false
129
+ # Note.new(rank: 0).rank? # => false
130
+ # Note.new(title: '').title? # => false
131
+ # Note.new(pinned: true).pinned? # => true
132
+ # Note.new(rank: 3).rank? # => true
133
+ def query_attribute(attr_name)
134
+ query_cast_attribute(attr_name, Errgonomic::Rails.unwrap_option(public_send(attr_name)))
135
+ end
136
+
137
+ # Rails copies query_attribute into attribute? at the alias, and the
138
+ # attr? methods it generates call that copy, so an override of the one
139
+ # never reaches them.
140
+ alias attribute? query_attribute
141
+ private :attribute?
142
+
118
143
  # YARD does not see through a concern's class_methods block, so the
119
144
  # method it documents is declared rather than read.
120
145
  #
@@ -5,8 +5,8 @@ require_relative 'variant_name'
5
5
  module Errgonomic
6
6
  module Result
7
7
  # The base class for Result's Ok and Err class variants. We implement as
8
- # much logic as possible here, and let Ok and Err handle their
9
- # initialization and self identification.
8
+ # much logic as possible here, including construction, and let Ok and
9
+ # Err handle only their self identification.
10
10
  class Any
11
11
  include Comparable
12
12
 
@@ -27,7 +27,7 @@ module Errgonomic
27
27
  # end # => Errgonomic::UnwrappedAccessError
28
28
  # Ok(1).respond_to?(:value) # => false
29
29
  # Ok(1).frozen? # => true
30
- # Err().frozen? # => true
30
+ # Err(:x).frozen? # => true
31
31
  def initialize(value)
32
32
  @value = value
33
33
  freeze
@@ -124,7 +124,7 @@ module Errgonomic
124
124
  # Ok(1) == 1 # => raise Errgonomic::TypeMismatchError, "Errgonomic::Result::Ok == Integer, which strict equality refuses.\nCompare Results (res == Ok(1)), test the inner value (res.ok_and? { |v| v == 1 }), or unwrap_or a fallback first."
125
125
  # Ok(1) != 1 # => raise Errgonomic::TypeMismatchError, "Errgonomic::Result::Ok != Integer, which strict equality refuses.\nCompare Results (res == Ok(1)), test the inner value (res.ok_and? { |v| v == 1 }), or unwrap_or a fallback first."
126
126
  # Ok(1) === 1 # => raise Errgonomic::TypeMismatchError, "Errgonomic::Result::Ok === Integer, which strict equality refuses.\nCompare Results (res == Ok(1)), test the inner value (res.ok_and? { |v| v == 1 }), or unwrap_or a fallback first."
127
- # Err() == nil # => raise Errgonomic::TypeMismatchError, "Errgonomic::Result::Err == NilClass, which strict equality refuses.\nCompare Results (res == Ok(nil)), test the inner value (res.ok_and? { |v| v == nil }), or unwrap_or a fallback first."
127
+ # Err(:x) == nil # => raise Errgonomic::TypeMismatchError, "Errgonomic::Result::Err == NilClass, which strict equality refuses.\nCompare Results (res == Ok(nil)), test the inner value (res.ok_and? { |v| v == nil }), or unwrap_or a fallback first."
128
128
  # Ok(1) === Ok(1) # => true
129
129
  # begin
130
130
  # [Ok(1)].include?(1)
@@ -132,7 +132,7 @@ module Errgonomic
132
132
  # e.class
133
133
  # end # => Errgonomic::TypeMismatchError
134
134
  # { Ok(1) => :v }[1] # => nil
135
- # nil == Err() # => false
135
+ # nil == Err(:x) # => false
136
136
  #
137
137
  # @example an Option is another container, not another Result
138
138
  # Ok(1) == Some(1) # => raise Errgonomic::TypeMismatchError, "Errgonomic::Result::Ok == Errgonomic::Option::Some, which strict equality refuses.\nA Result and an Option are different containers, and neither is the other.\nUnwrap the one you meant (res.unwrap_or(nil) == opt.unwrap_or(nil))."
@@ -468,35 +468,37 @@ module Errgonomic
468
468
  end
469
469
 
470
470
  # The Rust shape: each variant deconstructs to its one payload, so
471
- # `in Ok(v)` binds the value and `in Err(e)` binds the error. A
472
- # value-less Err deconstructs to nothing: the sentinel behind it is
473
- # internal and must never bind to a pattern variable.
471
+ # `in Ok(v)` binds the value and `in Err(e)` binds the error.
474
472
  #
475
473
  # @example
476
474
  # Ok(1).deconstruct # => [1]
477
- # Err(:e).deconstruct # => [:e]
478
- # Err().deconstruct # => []
475
+ # Err(:x).deconstruct # => [:x]
479
476
  # Ok(1).respond_to?(:deconstruct_keys) # => false
480
477
  #
481
- # @example a value-less Err matches `in Err` and `in Err()`, never `in Err(e)`
482
- # case Err()
483
- # in Err(e) then e
484
- # in Err then :no_value
485
- # end # => :no_value
486
- # case Err()
487
- # in Err() then :no_value
488
- # end # => :no_value
478
+ # @example every Err carries an error, so `in Err()` matches none of them
489
479
  # case Err(:x)
480
+ # in Err() then :empty
490
481
  # in Err(e) then e
491
- # in Err then :no_value
492
482
  # end # => :x
493
- # begin
494
- # case Err()
495
- # in Err(e) then e
496
- # end
497
- # rescue NoMatchingPatternError => e
498
- # e.class
499
- # end # => NoMatchingPatternError
483
+ # case Err(:x)
484
+ # in Err then :any_err
485
+ # end # => :any_err
486
+ # case Err(:x)
487
+ # in Err(_) then :any_err
488
+ # end # => :any_err
489
+ #
490
+ # @example an Err nested in an Ok matches through the Ok's payload
491
+ # case Ok(Err(:boom))
492
+ # in Ok(Err(e)) then e
493
+ # end # => :boom
494
+ # case Ok(Err(:boom))
495
+ # in Ok(Err()) then :empty
496
+ # in Ok(Err(_)) then :err_inside
497
+ # end # => :err_inside
498
+ # case Ok(Err(:boom))
499
+ # in Ok(Ok(value)) then value
500
+ # in Ok(Err) then :err_inside
501
+ # end # => :err_inside
500
502
  #
501
503
  # @example a two-branch case/in with no else is exhaustive
502
504
  # case Ok(1)
@@ -537,8 +539,6 @@ module Errgonomic
537
539
  # "Measurement produced an exception -- #{e.class}: #{e}"
538
540
  # end # => "Measurement produced an exception -- StandardError: nope"
539
541
  def deconstruct
540
- return [] if value.equal?(Err::Arbitrary)
541
-
542
542
  [value]
543
543
  end
544
544
 
@@ -608,19 +608,23 @@ module Errgonomic
608
608
  end
609
609
  end
610
610
 
611
- # The Err variant.
611
+ # The Err variant. It always carries an error, so unwrap_err! and a
612
+ # pattern variable bind what the caller put there.
613
+ #
614
+ # @example an Err without an error raises
615
+ # Err(:e).unwrap_err! # => :e
616
+ # Err() # => raise ArgumentError, "wrong number of arguments (given 0, expected 1)"
617
+ # Errgonomic::Result::Err.new # => raise ArgumentError, "wrong number of arguments (given 0, expected 1)"
618
+ #
619
+ # @example Err(nil) is an ordinary Err that holds nil
620
+ # Err(nil).inspect # => "Err(nil)"
621
+ # Err(nil).unwrap_err! # => nil
622
+ # Err(nil).deconstruct # => [nil]
623
+ # case Err(nil)
624
+ # in Ok(value) then [:ok, value]
625
+ # in Err(e) then [:err, e]
626
+ # end # => [:err, nil]
612
627
  class Err < Any
613
- class Arbitrary; end
614
-
615
- # Err may be constructed without a value, if you want.
616
- #
617
- # @example
618
- # Err(:y).unwrap_err! # => :y
619
- # Err().unwrap_err! # => Arbitrary
620
- def initialize(value = Arbitrary)
621
- super(value)
622
- end
623
-
624
628
  # Err is always err
625
629
  #
626
630
  # @example
@@ -637,15 +641,12 @@ module Errgonomic
637
641
  false
638
642
  end
639
643
 
640
- # Render like Rust's Debug; a value-less Err renders bare.
644
+ # Render like Rust's Debug, delegating to the inner value's inspect.
641
645
  #
642
646
  # @example
643
647
  # Err(:nope).inspect # => "Err(:nope)"
644
- # Err().inspect # => "Err()"
645
648
  # Err(Some(1)).inspect # => "Err(Some(1))"
646
649
  def inspect
647
- return 'Err()' if value.equal?(Arbitrary)
648
-
649
650
  "Err(#{value.inspect})"
650
651
  end
651
652
  end
@@ -687,7 +688,7 @@ def Ok(value)
687
688
  end
688
689
 
689
690
  # Global convenience method for constructing an Err result.
690
- def Err(value = Errgonomic::Result::Err::Arbitrary)
691
+ def Err(value)
691
692
  Errgonomic::Result::Err.new(value)
692
693
  end
693
694
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Errgonomic
4
- VERSION = '0.10.1'
4
+ VERSION = '0.11.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: errgonomic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Zadrozny