ronad 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|