Skip to content

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

License

Notifications You must be signed in to change notification settings

ParadoxV5/ruby-optionil

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

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?

About

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

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Languages