ronad 0.9.0 → 0.10.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/lib/ronad/many.rb +89 -0
- data/lib/ronad/maybe.rb +0 -22
- data/lib/ronad/monad.rb +23 -0
- data/lib/ronad/one.rb +26 -0
- data/lib/ronad/sugar.rb +4 -0
- data/lib/ronad/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aae96a5293971c4033fb68485338315e17f1f0c307e11f50c57f2e2583e81067
|
4
|
+
data.tar.gz: 3eecd824510dc9fa3ee01742797bac4c7a0ab7ffe949498a4c1d2074d320793f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5264e71387940e8728026b6fd524f0e237b81200c05e2abe4840d96a3ee7aa8e2d2e453af5e70dc117d2e9f4db0ed86c8052ee36bc49d632a670d17ffcd40927
|
7
|
+
data.tar.gz: 92b79c02a184d29a6a86ce2c01fdbc6efc201105d49debfcbd12bb68236ada59ac9f97683930ed8d7521bd1667e716e8fe502206b17a7dc6854883f2bfbaaaa3
|
data/lib/ronad/many.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
module Ronad
|
2
|
+
# Chain operations on lists that can possibly return other lists.
|
3
|
+
#
|
4
|
+
# sentence = 'hello-there my-friend@good-bye my-pal'
|
5
|
+
#
|
6
|
+
# words = sentence.split('@').flat_map do |partials|
|
7
|
+
# partials.split('-').map do |word|
|
8
|
+
# word + '!'
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# Or using Many:
|
13
|
+
#
|
14
|
+
# word = Many(sentence).split('@').split('-') + '!'
|
15
|
+
# words = word.value
|
16
|
+
#
|
17
|
+
# A Many can be useful for tranversing 'has many' relationships in a
|
18
|
+
# database. For example given the following relations with each relationship
|
19
|
+
# having 0 or more:
|
20
|
+
#
|
21
|
+
# - store has many products
|
22
|
+
# - product has many variants
|
23
|
+
# - variant has many inventory_units
|
24
|
+
#
|
25
|
+
# To obtain all the inventory_units of a store:
|
26
|
+
#
|
27
|
+
# store.products.flat_map(&:variants).flat_map(&:inventory_units)
|
28
|
+
#
|
29
|
+
# Or if a certain parameterized scope had to be used:
|
30
|
+
#
|
31
|
+
# store.products.flat_map do |product|
|
32
|
+
# prodcut.variants.where(some_state: true).flat_map do |variant|
|
33
|
+
# variant.inventory_units.where(physical: true)
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# With Many:
|
38
|
+
#
|
39
|
+
# Many(store).products.variants.where(some_state: true).inventory_units.where(physical: true)
|
40
|
+
# .value
|
41
|
+
#
|
42
|
+
# A Many will also remove nil values:
|
43
|
+
#
|
44
|
+
# Many([1,2,nil,4,nil]).value #=> [1,2,4]
|
45
|
+
class Many < Monad
|
46
|
+
# Wraps a value in the Many monad.
|
47
|
+
#
|
48
|
+
# @param value - Does not need to be an enumerable as
|
49
|
+
# it will be wrapped in an Array.
|
50
|
+
# @param return_lazy - specifies if #monad_value should return a lazy
|
51
|
+
# enumerator. If left as nil, then #monad_value will return a lazy
|
52
|
+
# enumerator if one was initially provided to the constructor.
|
53
|
+
def initialize(value, return_lazy: nil)
|
54
|
+
@return_lazy = if return_lazy.nil?
|
55
|
+
value.is_a? Enumerator::Lazy
|
56
|
+
else
|
57
|
+
return_lazy
|
58
|
+
end
|
59
|
+
|
60
|
+
if value.is_a? Enumerable
|
61
|
+
@value = value.lazy
|
62
|
+
else
|
63
|
+
@value = Array(value).lazy
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def and_then &b
|
69
|
+
from_value @value.reject(&:nil?).flat_map(&b)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the underlying value of the many. Always an Enumerator, sometimes
|
73
|
+
# lazy.
|
74
|
+
# @see #initialize
|
75
|
+
def monad_value
|
76
|
+
if @return_lazy
|
77
|
+
super
|
78
|
+
else
|
79
|
+
super.to_a
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
|
85
|
+
def from_value(value)
|
86
|
+
self.class.new(value, return_lazy: @return_lazy)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/ronad/maybe.rb
CHANGED
@@ -37,28 +37,6 @@ module Ronad
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
# "Fails" a maybe given a certain condition. If the condition is `false`
|
41
|
-
# then Maybe(nil) will be returned. Useful for performing side-effects
|
42
|
-
# given a certain condition
|
43
|
-
#
|
44
|
-
# Maybe([]).and_then do |value|
|
45
|
-
# value.each(&:some_operation)
|
46
|
-
# OtherModule.finalize! # Side Effect should only happen if there
|
47
|
-
# end # are any values
|
48
|
-
#
|
49
|
-
# The following `and_then` only executes if `value` responds truthy to any?
|
50
|
-
#
|
51
|
-
# Maybe([]).continue(&:any?).and_then do |value|
|
52
|
-
# value.each(&:some_operation)
|
53
|
-
# OtherModule.finalize!
|
54
|
-
# end
|
55
|
-
# @return [Monad]
|
56
|
-
def continue
|
57
|
-
and_then do |value|
|
58
|
-
value if yield value
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
40
|
# "Fails" a maybe given a certain condition. If the condition is `true`
|
63
41
|
# then Maybe(nil) will be returned.
|
64
42
|
#
|
data/lib/ronad/monad.rb
CHANGED
@@ -60,6 +60,29 @@ module Ronad
|
|
60
60
|
end
|
61
61
|
|
62
62
|
|
63
|
+
# "Fails" a maybe given a certain condition. If the condition is `false`
|
64
|
+
# then Maybe(nil) will be returned. Useful for performing side-effects
|
65
|
+
# given a certain condition
|
66
|
+
#
|
67
|
+
# Maybe([]).and_then do |value|
|
68
|
+
# value.each(&:some_operation)
|
69
|
+
# OtherModule.finalize! # Side Effect should only happen if there
|
70
|
+
# end # are any values
|
71
|
+
#
|
72
|
+
# The following `and_then` only executes if `value` responds truthy to any?
|
73
|
+
#
|
74
|
+
# Maybe([]).continue(&:any?).and_then do |value|
|
75
|
+
# value.each(&:some_operation)
|
76
|
+
# OtherModule.finalize!
|
77
|
+
# end
|
78
|
+
# @return [Monad]
|
79
|
+
def continue
|
80
|
+
and_then do |value|
|
81
|
+
value if yield value
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
63
86
|
private
|
64
87
|
|
65
88
|
# Provides convinience for chaining methods together while maintaining a
|
data/lib/ronad/one.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Ronad
|
2
|
+
# A One is similar to a Many but does not flatten the results if #and_then
|
3
|
+
# produces another list.
|
4
|
+
#
|
5
|
+
# urls = %w[
|
6
|
+
# example.com?p1=a&p2=b
|
7
|
+
# example.com?z1=5&y1=9
|
8
|
+
# ]
|
9
|
+
#
|
10
|
+
# one(urls)
|
11
|
+
# .split('?')
|
12
|
+
# .last # a Many would have flatten the #split and #last would be called on a String
|
13
|
+
# .split('&')
|
14
|
+
# .last
|
15
|
+
# .split('=')
|
16
|
+
# .first
|
17
|
+
# .value #=> ['p2', 'y1']
|
18
|
+
#
|
19
|
+
# A One can be used for providing a familiar interface to a function that
|
20
|
+
# does not expect the flattening behavior of Many.
|
21
|
+
class One < Many
|
22
|
+
def and_then &b
|
23
|
+
from_value @value.reject(&:nil?).map(&b)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/ronad/sugar.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
require 'ronad/maybe'
|
2
|
+
require 'ronad/many'
|
3
|
+
require 'ronad/one'
|
2
4
|
require 'ronad/just'
|
3
5
|
require 'ronad/just_one'
|
4
6
|
require 'ronad/default'
|
5
7
|
require 'ronad/eventually'
|
6
8
|
|
7
9
|
def Maybe(*values) ; Ronad::Maybe.from_multiple_values(*values) end
|
10
|
+
def Many(value, **kargs) ; Ronad::Many.new(value, **kargs) end
|
11
|
+
def One(value, **kargs) ; Ronad::One.new(value, **kargs) end
|
8
12
|
def Just(value); Ronad::Just.new(value) end
|
9
13
|
def JustOne(*values); Ronad::JustOne.new(*values) end
|
10
14
|
def Default(fallback, value) ; Ronad::Default.new(fallback, value) end
|
data/lib/ronad/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ronad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Uri Gorelik
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -101,8 +101,10 @@ files:
|
|
101
101
|
- lib/ronad/eventually.rb
|
102
102
|
- lib/ronad/just.rb
|
103
103
|
- lib/ronad/just_one.rb
|
104
|
+
- lib/ronad/many.rb
|
104
105
|
- lib/ronad/maybe.rb
|
105
106
|
- lib/ronad/monad.rb
|
107
|
+
- lib/ronad/one.rb
|
106
108
|
- lib/ronad/sugar.rb
|
107
109
|
- lib/ronad/version.rb
|
108
110
|
- lib/sugar.rb
|