optionil

Automatically apply the Optional pattern to all APIs globally, including the Ruby Corelib!


Keywords
anti-pattern, design-pattern
License
WTFPL
Install
gem install optionil -v 1.0

Documentation

This is an extremely simplistic (lol, only the 4 essential files) library that adds the Optional (anti)1 design pattern too ALL methods globally. It even supports logic operators (and, or, etc.)!

Synopsis

some = Optionil[42]        #=> Optionil::Some[42]
none = Optionil[nil]       #=> Optionil::None[] (you don't want Optionil::Some[nil], do you?…)
       Optionil::Some[nil] #!> NoMatchingPatternError (Do you???)
none.equal? Optionil[]     #=> true (the two are equivalent and all calls give the same constant)

Optionil::Some[]    #!> wrong number of arguments (given 0, expected 1) (ArgumentError)
Optionil::None[nil] #!> wrong number of arguments (given 1, expected 0) (ArgumentError)

Accessing

some.value #=> some
none.value #=> nil

some.value! #=> 42
none.value! #!> NoMatchingPatternError

some.value {      0      } # => some
some.value {    raise    } # => some
none.value {      0      } # => 0
none.value { Optionil[0] } # => Optionil::Some[0]

some.each {|n|     -n       } #=> -42
some.each {|n| Optionil[-n] } #=> Optionil::Some[-42]
none.each {|n|     -n       } #=> nil
none.each {|n|   raise      } #=> nil

Pattern Matching

Optionil       == some #=> true
Optionil       == none #=> true
Optionil::Some == some #=> true
Optionil::Some == none #=> false
Optionil::None == some #=> false
Optionil::None == none #=> true

some.some? #=> true
none.some? #=> false
some.none? #=> false
none.none? #=> true

some.some? Integer #=> true
some.some? String  #=> false
none.some? Integer #=> false

some.some? &:even? #=> true
some.some? &:odd?  #=> false
some.none? &:even? #=> false
some.none? &:odd?  #=> true

Logic Operation

!some #=> false
!none #=> true

som2 = Optionil::Some[-69]

some and som2 #=> som2
some and none #=> none
none and som2 #=> none

some or som2 #=> some
some or none #=> some
none or som2 #=> som2
none or none #=> none

som0 = Optional::Some[false]
!som0 #=> true
som0 and some #=> som0
# applies to `Optional::Some[nil]` as well

Method chaining

I’m intentionally not supporting this. Please tune in to pipeine operator discussions instead, such as https://bugs.ruby-lang.org/issues/20770.

License

Copyright © 2024 ParadoxV5

I made this little joke as entertainment in a day. I release it to the public domain; you can redistribute it and/or modify it under the “terms” of the Do What The Fuck You Want To Public License, Version 2.

Footnotes

  1. Cold take: the Optional pattern only exists because you can’t properlly handle nils.

    Yes, null is a billion-dollar mistake in traditional languages; but this is Ruby – we don’t have nulls, we have nils! A String can never be nil, only a String? (RBS) can!

    Even for, say Java, NonNull exists (JetBrains, Android, Lombok), so nullable variables are already Some|None Schrödinger boxes, why bother adding Option as another layer of wrapper? You’d think Optional[T]? wouldn’t be a thing? Do you need Optional[Optional[T]] for that? JavaScript already has both null and undefined, questionably, yet how many more types of nils do you still need? ↩