ramda-ruby 0.7.0 → 0.8.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/CHANGELOG.md +22 -1
- data/ROADMAP.md +0 -10
- data/docs/FUNCTIONS.md +16 -1
- data/lib/ramda.rb +20 -5
- data/lib/ramda/function.rb +17 -1
- data/lib/ramda/internal/functors.rb +44 -0
- data/lib/ramda/list.rb +18 -3
- data/lib/ramda/math.rb +6 -0
- data/lib/ramda/object.rb +134 -3
- data/lib/ramda/relation.rb +18 -0
- data/lib/ramda/type.rb +6 -0
- data/lib/ramda/version.rb +1 -1
- data/spec/ramda/function_spec.rb +7 -0
- data/spec/ramda/list_spec.rb +22 -1
- data/spec/ramda/math_spec.rb +6 -0
- data/spec/ramda/object_spec.rb +175 -2
- data/spec/ramda/relation_spec.rb +22 -0
- data/spec/ramda/type_spec.rb +12 -0
- data/spec/ramda_spec.rb +15 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28285eadf06563393e23d6cff7ad2f945a6b579e
|
4
|
+
data.tar.gz: 6efe04a0ec2340fa87d43ffcedf6b56b8c949ce8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8e29a9fceca691c212931de21d6c7972a17d4ff4f151ed0afb6457d3e6f4113a78498b209de824ce32ec40b46bb5f974c779a2728bcee8b86f70faaac3c4ccb
|
7
|
+
data.tar.gz: 7f525b162fd911a9117cbedcfcebe662af36b11345130eaa9faf15e67fbeff65c06a5297059c6cdc60a0f95e7c63f20b737053cf24f6e86c45664cfa7d802cf5
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
Not Released
|
2
2
|
---------------
|
3
3
|
|
4
|
+
Release 0.8.0
|
5
|
+
---------------
|
6
|
+
|
7
|
+
Added:
|
8
|
+
|
9
|
+
* assoc_path
|
10
|
+
* lens - composition does not work compose(lens1, lensb)
|
11
|
+
* lens_index
|
12
|
+
* lens_path
|
13
|
+
* lens_prop
|
14
|
+
* max_by
|
15
|
+
* min_by
|
16
|
+
* negate
|
17
|
+
* over
|
18
|
+
* pick_by
|
19
|
+
* set
|
20
|
+
* type
|
21
|
+
* unapply
|
22
|
+
* view
|
23
|
+
* update
|
24
|
+
|
4
25
|
Release 0.7.0
|
5
26
|
---------------
|
6
27
|
|
@@ -20,7 +41,7 @@ Added:
|
|
20
41
|
|
21
42
|
* F
|
22
43
|
* T
|
23
|
-
* __ - first function call should have all arguments g(
|
44
|
+
* `__` - first function call should have all arguments `g(__2, __)(1, 3)`, this means that it doesn't support `g(__, 2)(1)(3)`, `g(__, 2)(1, 3)` and `g(__, 2)(__, 3)(1)`
|
24
45
|
* bind
|
25
46
|
* cond
|
26
47
|
* prop_or
|
data/ROADMAP.md
CHANGED
data/docs/FUNCTIONS.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
* (pending) values_in
|
5
5
|
* F
|
6
6
|
* T
|
7
|
-
* __ - first function call should have all arguments g(
|
7
|
+
* `__` - first function call should have all arguments `g(__2, __)(1, 3)`, this means that it doesn't support `g(__, 2)(1)(3)`, `g(__, 2)(1, 3)` and `g(__, 2)(__, 3)(1)`
|
8
8
|
* add
|
9
9
|
* all
|
10
10
|
* all_pass
|
@@ -16,6 +16,7 @@
|
|
16
16
|
* append
|
17
17
|
* apply
|
18
18
|
* assoc
|
19
|
+
* assoc_path
|
19
20
|
* binary
|
20
21
|
* bind
|
21
22
|
* chain
|
@@ -73,6 +74,10 @@
|
|
73
74
|
* last
|
74
75
|
* last_index_of - returns nil if index doesn't exist
|
75
76
|
* length
|
77
|
+
* lens - composition does not work compose(lens1, lensb)
|
78
|
+
* lens_index
|
79
|
+
* lens_path
|
80
|
+
* lens_prop
|
76
81
|
* lift
|
77
82
|
* lift_n
|
78
83
|
* lt
|
@@ -80,23 +85,28 @@
|
|
80
85
|
* map
|
81
86
|
* match
|
82
87
|
* max
|
88
|
+
* max_by
|
83
89
|
* memoize
|
84
90
|
* merge
|
85
91
|
* min
|
92
|
+
* min_by
|
86
93
|
* modulo
|
87
94
|
* multiply
|
88
95
|
* n_ary
|
96
|
+
* negate
|
89
97
|
* not
|
90
98
|
* nth
|
91
99
|
* of
|
92
100
|
* omit
|
93
101
|
* once
|
94
102
|
* or
|
103
|
+
* over
|
95
104
|
* partition
|
96
105
|
* path
|
97
106
|
* path_eq
|
98
107
|
* pick
|
99
108
|
* pick_all
|
109
|
+
* pick_by
|
100
110
|
* pipe
|
101
111
|
* pluck
|
102
112
|
* prepend
|
@@ -114,6 +124,7 @@
|
|
114
124
|
* repeat
|
115
125
|
* replace - it uses a gsub method and global replacement
|
116
126
|
* reverse
|
127
|
+
* set
|
117
128
|
* slice
|
118
129
|
* sort
|
119
130
|
* sort_by
|
@@ -129,14 +140,18 @@
|
|
129
140
|
* to_pairs
|
130
141
|
* to_upper
|
131
142
|
* trim
|
143
|
+
* type
|
144
|
+
* unapply
|
132
145
|
* unary
|
133
146
|
* union
|
134
147
|
* union_with
|
135
148
|
* uniq
|
136
149
|
* uniq_with - first argument is a function with 1 arity which transforms each list element and applies uniq function to results
|
137
150
|
* unnest
|
151
|
+
* update
|
138
152
|
* use_with
|
139
153
|
* values
|
154
|
+
* view
|
140
155
|
* where
|
141
156
|
* xprod
|
142
157
|
* zip
|
data/lib/ramda.rb
CHANGED
@@ -44,6 +44,7 @@ module Ramda
|
|
44
44
|
:once,
|
45
45
|
:pipe,
|
46
46
|
:tap,
|
47
|
+
:unapply,
|
47
48
|
:unary,
|
48
49
|
:use_with
|
49
50
|
|
@@ -92,6 +93,7 @@ module Ramda
|
|
92
93
|
:uniq,
|
93
94
|
:uniq_with,
|
94
95
|
:unnest,
|
96
|
+
:update,
|
95
97
|
:xprod,
|
96
98
|
:zip,
|
97
99
|
:zip_obj,
|
@@ -109,39 +111,49 @@ module Ramda
|
|
109
111
|
:or
|
110
112
|
|
111
113
|
def_delegators Ramda::Math,
|
114
|
+
# :math_mod,
|
112
115
|
:add,
|
113
116
|
:dec,
|
114
117
|
:divide,
|
115
118
|
:inc,
|
116
|
-
# :math_mod,
|
117
119
|
:modulo,
|
118
120
|
:multiply,
|
121
|
+
:negate,
|
119
122
|
:product,
|
120
123
|
:subtract,
|
121
124
|
:sum
|
122
125
|
|
123
126
|
def_delegators Ramda::Object,
|
127
|
+
# :keys_in,
|
128
|
+
# :to_pairs_in,
|
129
|
+
# :values_in,
|
124
130
|
:assoc,
|
131
|
+
:assoc_path,
|
125
132
|
:clone,
|
126
133
|
:dissoc,
|
127
134
|
:eq_props,
|
128
135
|
:has,
|
129
136
|
:has_in,
|
130
137
|
:keys,
|
131
|
-
|
138
|
+
:lens,
|
139
|
+
:lens_index,
|
140
|
+
:lens_path,
|
141
|
+
:lens_prop,
|
132
142
|
:merge,
|
133
143
|
:omit,
|
144
|
+
:over,
|
134
145
|
:path,
|
135
146
|
:pick,
|
136
147
|
:pick_all,
|
148
|
+
:pick_by,
|
137
149
|
:project,
|
138
150
|
:prop,
|
139
151
|
:prop_or,
|
140
152
|
:props,
|
153
|
+
:set,
|
141
154
|
:to_pairs,
|
142
|
-
# :to_pairs_in,
|
143
155
|
:values,
|
144
|
-
|
156
|
+
:view,
|
145
157
|
:where
|
146
158
|
|
147
159
|
def_delegators Ramda::Relation,
|
@@ -156,7 +168,9 @@ module Ramda
|
|
156
168
|
:lt,
|
157
169
|
:lte,
|
158
170
|
:max,
|
171
|
+
:max_by,
|
159
172
|
:min,
|
173
|
+
:min_by,
|
160
174
|
:path_eq,
|
161
175
|
:prop_eq,
|
162
176
|
:sort_by,
|
@@ -173,5 +187,6 @@ module Ramda
|
|
173
187
|
|
174
188
|
def_delegators Ramda::Type,
|
175
189
|
:is,
|
176
|
-
:is_nil
|
190
|
+
:is_nil,
|
191
|
+
:type
|
177
192
|
end
|
data/lib/ramda/function.rb
CHANGED
@@ -337,7 +337,7 @@ module Ramda
|
|
337
337
|
# (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)
|
338
338
|
#
|
339
339
|
curried_method(:pipe) do |*fns|
|
340
|
-
->(*args) { fns.reduce(args) { |memo, fn|
|
340
|
+
->(*args) { fns[1..-1].reduce(fns[0].call(*args)) { |memo, fn| fn.call(memo) } }
|
341
341
|
end
|
342
342
|
|
343
343
|
# Runs the given function with the supplied object, then returns the object.
|
@@ -349,6 +349,22 @@ module Ramda
|
|
349
349
|
x
|
350
350
|
end
|
351
351
|
|
352
|
+
# Takes a function fn, which takes a single array argument, and returns a
|
353
|
+
# function which:
|
354
|
+
#
|
355
|
+
# * takes any number of positional arguments;
|
356
|
+
# * passes these arguments to fn as an array; and
|
357
|
+
# * returns the result.
|
358
|
+
#
|
359
|
+
# In other words, R.unapply derives a variadic function from a function
|
360
|
+
# which takes an array. R.unapply is the inverse of R.apply.
|
361
|
+
#
|
362
|
+
# ([*...] -> a) -> (*... -> a)
|
363
|
+
#
|
364
|
+
curried_method(:unapply) do |fn, x, *xs|
|
365
|
+
fn.call([x] + xs)
|
366
|
+
end
|
367
|
+
|
352
368
|
# Wraps a function of any arity (including nullary) in a function that
|
353
369
|
# accepts exactly 1 parameter. Any extraneous parameters will not be passed
|
354
370
|
# to the supplied function.
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Ramda
|
2
|
+
module Internals
|
3
|
+
module Functors
|
4
|
+
# `const` is a functor that effectively ignores the function given to `map`.
|
5
|
+
class Const
|
6
|
+
attr_reader :value
|
7
|
+
|
8
|
+
def self.of(x)
|
9
|
+
new(x)
|
10
|
+
end
|
11
|
+
|
12
|
+
def map(*)
|
13
|
+
Const.of(@value)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def initialize(value)
|
19
|
+
@value = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# `Identity` is a functor that holds a single value, where `map` simply
|
24
|
+
# transforms the held value with the provided function.
|
25
|
+
class Identity
|
26
|
+
attr_reader :value
|
27
|
+
|
28
|
+
def self.of(x)
|
29
|
+
new(x)
|
30
|
+
end
|
31
|
+
|
32
|
+
def map(f)
|
33
|
+
Identity.of(f.call(@value))
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def initialize(value)
|
39
|
+
@value = value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/ramda/list.rb
CHANGED
@@ -258,6 +258,8 @@ module Ramda
|
|
258
258
|
# Ramda provides suitable map implementations for Array and Object,
|
259
259
|
# so this function may be applied to [1, 2, 3] or {x: 1, y: 2, z: 3}.
|
260
260
|
#
|
261
|
+
# Also treats functions as functors and will compose them together.
|
262
|
+
#
|
261
263
|
# Functor f => (a -> b) -> f a -> f b
|
262
264
|
#
|
263
265
|
curried_method(:map) do |f, functor|
|
@@ -267,7 +269,11 @@ module Ramda
|
|
267
269
|
when ::Array
|
268
270
|
functor.map(&f)
|
269
271
|
else
|
270
|
-
|
272
|
+
if functor.respond_to?(:map)
|
273
|
+
functor.map(f)
|
274
|
+
else
|
275
|
+
type_error(functor, :map)
|
276
|
+
end
|
271
277
|
end
|
272
278
|
end
|
273
279
|
|
@@ -281,8 +287,8 @@ module Ramda
|
|
281
287
|
case xs
|
282
288
|
when ::String
|
283
289
|
xs[index] || ''
|
284
|
-
when ::Array
|
285
|
-
xs
|
290
|
+
when ::Array, ::Hash
|
291
|
+
xs.fetch(index, nil)
|
286
292
|
else
|
287
293
|
type_error(xs, :nth)
|
288
294
|
end
|
@@ -475,6 +481,15 @@ module Ramda
|
|
475
481
|
Ramda.chain(Ramda.identity, xs)
|
476
482
|
end
|
477
483
|
|
484
|
+
# Returns a new copy of the array with the element at the provided
|
485
|
+
# index replaced with the given value.
|
486
|
+
#
|
487
|
+
# Number -> a -> [a] -> [a]
|
488
|
+
#
|
489
|
+
curried_method(:update) do |idx, x, xs|
|
490
|
+
xs.dup.tap { |a| a[idx] = x }
|
491
|
+
end
|
492
|
+
|
478
493
|
# Creates a new list out of the two supplied by creating each possible pair
|
479
494
|
# from the lists.
|
480
495
|
#
|
data/lib/ramda/math.rb
CHANGED
data/lib/ramda/object.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
require_relative 'internal/curried_method'
|
2
|
+
require_relative 'internal/functors'
|
2
3
|
|
3
4
|
module Ramda
|
4
5
|
# Math functions
|
6
|
+
# rubocop:disable Metrics/ModuleLength
|
5
7
|
module Object
|
6
8
|
extend ::Ramda::Internal::CurriedMethod
|
7
9
|
|
10
|
+
Functors = ::Ramda::Internals::Functors
|
11
|
+
|
8
12
|
# Makes a shallow clone of an object, setting or overriding the specified
|
9
13
|
# property with the given value. Note that this copies and flattens
|
10
14
|
# prototype properties onto the new object as well. All non-primitive
|
@@ -16,6 +20,32 @@ module Ramda
|
|
16
20
|
obj.merge(key => val)
|
17
21
|
end
|
18
22
|
|
23
|
+
# Makes a shallow clone of an object, setting or overriding the nodes
|
24
|
+
# required to create the given path, and placing the specific value at
|
25
|
+
# the tail end of that path. Note that this copies and flattens
|
26
|
+
# prototype properties onto the new object as well. All non-primitive
|
27
|
+
# properties are copied by reference.
|
28
|
+
#
|
29
|
+
# [Idx] -> a -> {a} -> {a}
|
30
|
+
# Idx = String | Int
|
31
|
+
#
|
32
|
+
curried_method(:assoc_path) do |path, val, obj|
|
33
|
+
if path.empty?
|
34
|
+
val
|
35
|
+
else
|
36
|
+
cloned = clone(obj)
|
37
|
+
path[0...-1].reduce(cloned) do |acc, k|
|
38
|
+
case acc[k]
|
39
|
+
when Hash, Array
|
40
|
+
acc[k]
|
41
|
+
else
|
42
|
+
acc[k] = k.is_a?(Integer) ? [] : {}
|
43
|
+
end
|
44
|
+
end[path[-1]] = val
|
45
|
+
cloned
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
19
49
|
# Creates a deep copy of the value which may contain (nested)
|
20
50
|
# Arrays and Objects, Numbers, Strings, Booleans and Dates.
|
21
51
|
# Functions are assigned by reference rather than copied
|
@@ -24,8 +54,14 @@ module Ramda
|
|
24
54
|
#
|
25
55
|
curried_method(:clone) do |obj|
|
26
56
|
case obj
|
57
|
+
when Hash
|
58
|
+
obj.each_with_object(obj.dup) do |(key, value), acc|
|
59
|
+
acc[clone(key)] = clone(value)
|
60
|
+
end
|
27
61
|
when Array
|
28
|
-
obj.
|
62
|
+
obj.map(&clone)
|
63
|
+
when Symbol, Integer, NilClass, TrueClass, FalseClass
|
64
|
+
obj
|
29
65
|
else
|
30
66
|
obj.dup
|
31
67
|
end
|
@@ -86,6 +122,51 @@ module Ramda
|
|
86
122
|
.uniq
|
87
123
|
end
|
88
124
|
|
125
|
+
# Returns a lens for the given getter and setter functions.
|
126
|
+
# The getter "gets" the value of the focus;
|
127
|
+
# the setter "sets" the value of the focus.
|
128
|
+
# The setter should not mutate the data structure.
|
129
|
+
#
|
130
|
+
# (s -> a) -> ((a, s) -> s) -> Lens s a
|
131
|
+
# Lens s a = Functor f => (a -> f a) -> s -> f s
|
132
|
+
#
|
133
|
+
curried_method(:lens) do |getter, setter|
|
134
|
+
curried_method_body(:lens, 2) do |to_functor_fn, target|
|
135
|
+
Ramda.map(
|
136
|
+
->(focus) { setter.call(focus, target) },
|
137
|
+
to_functor_fn.call(getter.call(target))
|
138
|
+
)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns a lens whose focus is the specified index.
|
143
|
+
#
|
144
|
+
# Number -> Lens s a
|
145
|
+
# Lens s a = Functor f => (a -> f a) -> s -> f s
|
146
|
+
#
|
147
|
+
curried_method(:lens_index) do |n|
|
148
|
+
lens(Ramda.nth(0), Ramda.update(n))
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns a lens whose focus is the specified path.
|
152
|
+
#
|
153
|
+
# [Idx] -> Lens s a
|
154
|
+
# Idx = String | Int
|
155
|
+
# Lens s a = Functor f => (a -> f a) -> s -> f s
|
156
|
+
#
|
157
|
+
curried_method(:lens_path) do |path|
|
158
|
+
lens(Ramda.path(path), Ramda.assoc_path(path))
|
159
|
+
end
|
160
|
+
|
161
|
+
# Returns a lens whose focus is the specified property.
|
162
|
+
#
|
163
|
+
# String -> Lens s a
|
164
|
+
# Lens s a = Functor f => (a -> f a) -> s -> f s
|
165
|
+
#
|
166
|
+
curried_method(:lens_prop) do |k|
|
167
|
+
lens(Ramda.prop(k), Ramda.assoc(k))
|
168
|
+
end
|
169
|
+
|
89
170
|
# Create a new object with the own properties of the first object merged
|
90
171
|
# with the own properties of the second object. If a key exists in both
|
91
172
|
# objects, the value from the second object will be used.
|
@@ -101,18 +182,34 @@ module Ramda
|
|
101
182
|
# [String] -> {String: *} -> {String: *}
|
102
183
|
#
|
103
184
|
curried_method(:omit) do |keys, obj|
|
104
|
-
obj_copy = obj
|
185
|
+
obj_copy = clone(obj)
|
105
186
|
keys.each(&obj_copy.method(:delete))
|
106
187
|
obj_copy
|
107
188
|
end
|
108
189
|
|
190
|
+
# Returns the result of "setting" the portion of the given data
|
191
|
+
# structure focused by the given lens to the result of applying
|
192
|
+
# the given function to the focused value.
|
193
|
+
#
|
194
|
+
# Lens s a -> (a -> a) -> s -> s
|
195
|
+
# Lens s a = Functor f => (a -> f a) -> s -> f s
|
196
|
+
#
|
197
|
+
curried_method(:over) do |lens, f, x|
|
198
|
+
# The value returned by the getter function is first transformed with `f`,
|
199
|
+
# then set as the value of an `Identity`. This is then mapped over with the
|
200
|
+
# setter function of the lens.
|
201
|
+
lens
|
202
|
+
.call(->(y) { Functors::Identity.of(y).map(f) }, x)
|
203
|
+
.value
|
204
|
+
end
|
205
|
+
|
109
206
|
# Retrieve the value at a given path.
|
110
207
|
#
|
111
208
|
# [Idx] -> {a} -> a | NilClass
|
112
209
|
# Idx = String | Int
|
113
210
|
#
|
114
211
|
curried_method(:path) do |keys, obj|
|
115
|
-
keys.reduce(obj) { |acc, key| acc.
|
212
|
+
keys.reduce(obj) { |acc, key| acc.respond_to?(:fetch) ? acc.fetch(key, nil) : nil }
|
116
213
|
end
|
117
214
|
|
118
215
|
# Returns a partial copy of an object containing only the keys specified.
|
@@ -133,6 +230,15 @@ module Ramda
|
|
133
230
|
Hash[keys.map { |k| [k, obj.key?(k) ? obj.fetch(k) : nil] }]
|
134
231
|
end
|
135
232
|
|
233
|
+
# Returns a partial copy of an object containing only the keys that
|
234
|
+
# satisfy the supplied predicate.
|
235
|
+
#
|
236
|
+
# (v, k -> Boolean) -> {k: v} -> {k: v}
|
237
|
+
#
|
238
|
+
curried_method(:pick_by) do |fn, obj|
|
239
|
+
obj.select { |k, v| fn.call(v, k) }
|
240
|
+
end
|
241
|
+
|
136
242
|
# Reasonable analog to SQL select statement.
|
137
243
|
#
|
138
244
|
# [k] -> [{k: v}] -> [{k: v}]
|
@@ -174,6 +280,16 @@ module Ramda
|
|
174
280
|
keys.map(&obj.method(:[]))
|
175
281
|
end
|
176
282
|
|
283
|
+
# Returns the result of "setting" the portion of the given data structure
|
284
|
+
# focused by the given lens to the given value.
|
285
|
+
#
|
286
|
+
# Lens s a -> a -> s -> s
|
287
|
+
# Lens s a = Functor f => (a -> f a) -> s -> f s
|
288
|
+
#
|
289
|
+
curried_method(:set) do |lens, v, x|
|
290
|
+
over(lens, Ramda.always(v), x)
|
291
|
+
end
|
292
|
+
|
177
293
|
# Converts an object into an array of key, value arrays. Only the
|
178
294
|
# object's own properties are used. Note that the order of the
|
179
295
|
# output array is not guaranteed.
|
@@ -197,6 +313,21 @@ module Ramda
|
|
197
313
|
keys_in(obj).map(&obj.method(:send))
|
198
314
|
end
|
199
315
|
|
316
|
+
# Returns a "view" of the given data structure, determined
|
317
|
+
# by the given lens. The lens's focus determines which portion
|
318
|
+
# of the data structure is visible.
|
319
|
+
#
|
320
|
+
# Lens s a -> s -> a
|
321
|
+
# Lens s a = Functor f => (a -> f a) -> s -> f s
|
322
|
+
#
|
323
|
+
curried_method(:view) do |lens, x|
|
324
|
+
# Using `const` effectively ignores the setter function of the `lens`,
|
325
|
+
# leaving the value returned by the getter function unmodified.
|
326
|
+
lens
|
327
|
+
.call(Functors::Const.method(:of), x)
|
328
|
+
.value
|
329
|
+
end
|
330
|
+
|
200
331
|
# Takes a spec object and a test object; returns true if the test satisfies
|
201
332
|
# the spec. Each of the spec's own properties must be a predicate function.
|
202
333
|
# Each predicate is applied to the value of the corresponding property of
|
data/lib/ramda/relation.rb
CHANGED
@@ -111,6 +111,15 @@ module Ramda
|
|
111
111
|
[a, b].max
|
112
112
|
end
|
113
113
|
|
114
|
+
# Takes a function and two values, and returns whichever value produces
|
115
|
+
# the larger result when passed to the provided function.
|
116
|
+
#
|
117
|
+
# Ord b => (a -> b) -> a -> a -> a
|
118
|
+
#
|
119
|
+
curried_method(:max_by) do |fn, a, b|
|
120
|
+
[a, b].max_by(&fn)
|
121
|
+
end
|
122
|
+
|
114
123
|
# Returns the smaller of its two arguments.
|
115
124
|
#
|
116
125
|
# Ord a => a -> a -> a
|
@@ -119,6 +128,15 @@ module Ramda
|
|
119
128
|
[a, b].min
|
120
129
|
end
|
121
130
|
|
131
|
+
# Takes a function and two values, and returns whichever value
|
132
|
+
# produces the smaller result when passed to the provided function.
|
133
|
+
#
|
134
|
+
# Ord b => (a -> b) -> a -> a -> a
|
135
|
+
#
|
136
|
+
curried_method(:min_by) do |fn, a, b|
|
137
|
+
[a, b].min_by(&fn)
|
138
|
+
end
|
139
|
+
|
122
140
|
# Determines whether a nested path on an object has a specific value,
|
123
141
|
# in R.equals terms. Most likely used to filter a list.
|
124
142
|
#
|
data/lib/ramda/type.rb
CHANGED
data/lib/ramda/version.rb
CHANGED
data/spec/ramda/function_spec.rb
CHANGED
@@ -392,6 +392,13 @@ describe Ramda::Function do
|
|
392
392
|
end
|
393
393
|
end
|
394
394
|
|
395
|
+
context '#unapply' do
|
396
|
+
it 'from docs' do
|
397
|
+
stringify = ->(args) { args.to_s }
|
398
|
+
expect(r.unapply(stringify).call(1, 2, 3)).to eq('[1, 2, 3]')
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
395
402
|
context '#unary' do
|
396
403
|
it 'from docs' do
|
397
404
|
takes_two_args = ->(a, b) { [a, b] }
|
data/spec/ramda/list_spec.rb
CHANGED
@@ -309,15 +309,23 @@ describe Ramda::List do
|
|
309
309
|
end
|
310
310
|
|
311
311
|
context '#nth' do
|
312
|
-
it '
|
312
|
+
it 'with array' do
|
313
313
|
list = ['foo', 'bar', 'baz', 'quux']
|
314
314
|
expect(r.nth(1, list)).to eq('bar')
|
315
315
|
expect(r.nth(-1, list)).to eq('quux')
|
316
316
|
expect(r.nth(-99, list)).to be_nil
|
317
|
+
end
|
317
318
|
|
319
|
+
it 'with string' do
|
318
320
|
expect(r.nth(2, 'abc')).to eq('c')
|
319
321
|
expect(r.nth(3, 'abc')).to eq('')
|
320
322
|
end
|
323
|
+
|
324
|
+
it 'with hash' do
|
325
|
+
list = { a: 123 }
|
326
|
+
expect(r.nth(:a, list)).to eq(123)
|
327
|
+
expect(r.nth(:b, list)).to be_nil
|
328
|
+
end
|
321
329
|
end
|
322
330
|
|
323
331
|
context '#partition' do
|
@@ -526,6 +534,19 @@ describe Ramda::List do
|
|
526
534
|
end
|
527
535
|
end
|
528
536
|
|
537
|
+
context '#update' do
|
538
|
+
it 'without mutation' do
|
539
|
+
original = [0, 1, 2]
|
540
|
+
updated = r.update(1, 11, original)
|
541
|
+
expect(updated).to eq([0, 11, 2])
|
542
|
+
expect(original).to eq([0, 1, 2])
|
543
|
+
end
|
544
|
+
|
545
|
+
it 'is curried' do
|
546
|
+
expect(r.update(1).call(11).call([0, 1, 2])).to eq([0, 11, 2])
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
529
550
|
context '#xprod' do
|
530
551
|
it 'from docs' do
|
531
552
|
expect(r.xprod([1, 2], ['a', 'b']))
|
data/spec/ramda/math_spec.rb
CHANGED
data/spec/ramda/object_spec.rb
CHANGED
@@ -9,6 +9,23 @@ describe Ramda::Object do
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
context '#assoc_path' do
|
13
|
+
it 'from docs' do
|
14
|
+
expect(r.assoc_path([:a, :b, :c], 42, a: { b: { c: 0 } })).to eq(a: { b: { c: 42 } })
|
15
|
+
expect(r.assoc_path([:a, :b, :c], 42, a: 5)).to eq(a: { b: { c: 42 } })
|
16
|
+
expect(r.assoc_path([:a, :b, :c], 42, a: 5, d: 10)).to eq(a: { b: { c: 42 } }, d: 10)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'with object + array' do
|
20
|
+
obj = { x: [{ y: 2, z: 3 }, { y: 4, z: 5 }] }
|
21
|
+
expect(r.assoc_path([:x, 0, :y], 1, obj)).to eq(x: [{ y: 1, z: 3 }, { y: 4, z: 5 }])
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'empty path replaces the the whole object' do
|
25
|
+
expect(r.assoc_path([], 3, a: 1, b: 2)).to eq(3)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
12
29
|
context '#clone' do
|
13
30
|
it 'from docs' do
|
14
31
|
objects = [{}, {}, {}]
|
@@ -16,6 +33,31 @@ describe Ramda::Object do
|
|
16
33
|
expect(objects).not_to be(objects_clone)
|
17
34
|
expect(objects[0]).not_to be(objects_clone[0])
|
18
35
|
end
|
36
|
+
|
37
|
+
it 'nested arrays' do
|
38
|
+
obj = [1, [2, 2, [3, 3]]]
|
39
|
+
|
40
|
+
cloned = r.clone(obj)
|
41
|
+
cloned[1][2][0] = 100
|
42
|
+
|
43
|
+
expect(cloned).not_to eq(obj)
|
44
|
+
path = Ramda.path([1, 2])
|
45
|
+
expect(path.call(obj)).to eq([3, 3])
|
46
|
+
expect(path.call(cloned)).to eq([100, 3])
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'nested objects' do
|
50
|
+
obj = { a: { b: { c: 10 } } }
|
51
|
+
|
52
|
+
cloned = r.clone(obj)
|
53
|
+
cloned[:a][:b][:c] = 100
|
54
|
+
|
55
|
+
expect(cloned).not_to eq(obj)
|
56
|
+
|
57
|
+
path = Ramda.path([:a, :b])
|
58
|
+
expect(path.call(obj)).to eq(c: 10)
|
59
|
+
expect(path.call(cloned)).to eq(c: 100)
|
60
|
+
end
|
19
61
|
end
|
20
62
|
|
21
63
|
context '#dissoc' do
|
@@ -26,7 +68,7 @@ describe Ramda::Object do
|
|
26
68
|
|
27
69
|
context '#has' do
|
28
70
|
it 'from docs' do
|
29
|
-
has_name =
|
71
|
+
has_name = r.has(:name)
|
30
72
|
expect(has_name.call(name: 'alice')).to be_truthy
|
31
73
|
expect(has_name.call(name: 'bob')).to be_truthy
|
32
74
|
expect(has_name.call({})).to be_falsey
|
@@ -34,7 +76,7 @@ describe Ramda::Object do
|
|
34
76
|
|
35
77
|
it 'with placeholder' do
|
36
78
|
point = { x: 0, y: 0 }
|
37
|
-
point_has =
|
79
|
+
point_has = r.has(R.__, point)
|
38
80
|
expect(point_has.call(:x)).to be_truthy
|
39
81
|
expect(point_has.call(:y)).to be_truthy
|
40
82
|
expect(point_has.call(:z)).to be_falsey
|
@@ -87,6 +129,124 @@ describe Ramda::Object do
|
|
87
129
|
end
|
88
130
|
end
|
89
131
|
|
132
|
+
context '#lens' do
|
133
|
+
def x_lens
|
134
|
+
r.lens(R.prop(:x), R.assoc(:x))
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'with view' do
|
138
|
+
expect(R.view(x_lens, x: 1, y: 2)).to eq(1)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'with set' do
|
142
|
+
expect(R.set(x_lens, 4, x: 1, y: 2)).to eq(x: 4, y: 2)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'with over' do
|
146
|
+
expect(R.over(x_lens, R.negate, x: 1, y: 2)).to eq(x: -1, y: 2)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context '#lens_index' do
|
151
|
+
it 'from docs' do
|
152
|
+
head_lens = r.lens_index(0)
|
153
|
+
|
154
|
+
expect(R.view(head_lens, ['a', 'b', 'c'])).to eq('a')
|
155
|
+
expect(R.set(head_lens, 'x', ['a', 'b', 'c'])).to eq(['x', 'b', 'c'])
|
156
|
+
expect(R.over(head_lens, R.to_upper, ['a', 'b', 'c'])).to eq(['A', 'b', 'c'])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context '#lens_path' do
|
161
|
+
it 'from docs' do
|
162
|
+
x_head_y_lens = r.lens_path([:x, 0, :y])
|
163
|
+
|
164
|
+
obj = { x: [{ y: 2, z: 3 }, { y: 4, z: 5 }] }
|
165
|
+
|
166
|
+
expect(R.view(x_head_y_lens, obj)).to eq(2)
|
167
|
+
expect(R.set(x_head_y_lens, 1, obj)).to eq(x: [{ y: 1, z: 3 }, { y: 4, z: 5 }])
|
168
|
+
expect(R.over(x_head_y_lens, R.negate, obj)).to eq(x: [{ y: -2, z: 3 }, { y: 4, z: 5 }])
|
169
|
+
|
170
|
+
expect(obj).to eq(x: [{ y: 2, z: 3 }, { y: 4, z: 5 }])
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context '#lens_prop' do
|
175
|
+
it 'from docs' do
|
176
|
+
x_lens = r.lens_prop(:x)
|
177
|
+
|
178
|
+
expect(R.view(x_lens, x: 1, y: 2)).to eq(1)
|
179
|
+
expect(R.set(x_lens, 4, x: 1, y: 2)).to eq(x: 4, y: 2)
|
180
|
+
expect(R.over(x_lens, R.negate, x: 1, y: 2)).to eq(x: -1, y: 2)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'view, over, and set' do
|
185
|
+
let(:alice) do
|
186
|
+
{
|
187
|
+
name: 'Alice Jones',
|
188
|
+
address: ['22 Walnut St', 'San Francisco', 'CA'],
|
189
|
+
pets: { dog: 'joker', cat: 'batman' }
|
190
|
+
}
|
191
|
+
end
|
192
|
+
let(:head_lens) { R.lens_index(0) }
|
193
|
+
|
194
|
+
it 'may be applied to a lens created by `lens_path`' do
|
195
|
+
dog_lens = R.lens_path([:pets, :dog])
|
196
|
+
expect(r.view(dog_lens, alice)).to eq('joker')
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'may be applied to a lens created by `lens_prop`' do
|
200
|
+
name_lens = R.lens(R.prop(:name), R.assoc(:name))
|
201
|
+
|
202
|
+
expect(r.view(name_lens, alice)).to eq('Alice Jones')
|
203
|
+
|
204
|
+
expect(r.over(name_lens, R.to_upper, alice)).to eq(
|
205
|
+
name: 'ALICE JONES',
|
206
|
+
address: ['22 Walnut St', 'San Francisco', 'CA'],
|
207
|
+
pets: { dog: 'joker', cat: 'batman' }
|
208
|
+
)
|
209
|
+
|
210
|
+
expect(r.set(name_lens, 'Alice Smith', alice)).to eq(
|
211
|
+
name: 'Alice Smith',
|
212
|
+
address: ['22 Walnut St', 'San Francisco', 'CA'],
|
213
|
+
pets: { dog: 'joker', cat: 'batman' }
|
214
|
+
)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'may be applied to a lens created by `lens_index`' do
|
218
|
+
expect(R.view(head_lens, alice.fetch(:address))).to eq('22 Walnut St')
|
219
|
+
|
220
|
+
expect(R.over(head_lens, R.to_upper, alice.fetch(:address)))
|
221
|
+
.to eq(['22 WALNUT ST', 'San Francisco', 'CA'])
|
222
|
+
|
223
|
+
expect(R.set(head_lens, '52 Crane Ave', alice.fetch(:address)))
|
224
|
+
.to eq(['52 Crane Ave', 'San Francisco', 'CA'])
|
225
|
+
end
|
226
|
+
|
227
|
+
xit 'may be applied to composed lenses' do
|
228
|
+
address_lens = R.lens_prop(:address)
|
229
|
+
street_lens = R.compose(address_lens, head_lens)
|
230
|
+
dog_lens = R.compose(R.lens_path([:pets]), R.lens_path([:dog]))
|
231
|
+
|
232
|
+
expect(R.view(dog_lens, alice)).to eq(R.view(R.lens_path([:pets, :dog]), alice))
|
233
|
+
|
234
|
+
expect(R.view(street_lens, alice)).to eq('22 Walnut St')
|
235
|
+
|
236
|
+
expect(R.over(street_lens, R.to_upper, alice)).to eq(
|
237
|
+
name: 'Alice Jones',
|
238
|
+
address: ['22 WALNUT ST', 'San Francisco', 'CA'],
|
239
|
+
pets: { dog: 'joker', cat: 'batman' }
|
240
|
+
)
|
241
|
+
|
242
|
+
expect(R.set(street_lens, '52 Crane Ave', alice)).to eq(
|
243
|
+
name: 'Alice Jones',
|
244
|
+
address: ['52 Crane Ave', 'San Francisco', 'CA'],
|
245
|
+
pets: { dog: 'joker', cat: 'batman' }
|
246
|
+
)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
90
250
|
context '#merge' do
|
91
251
|
it 'from docs' do
|
92
252
|
expect(r.merge({ name: 'fred', age: 10 }, age: 40))
|
@@ -114,6 +274,11 @@ describe Ramda::Object do
|
|
114
274
|
expect(r.path([:a, :b], a: { b: 2 })).to eq(2)
|
115
275
|
expect(r.path([:a, :b], c: { b: 2 })).to eq(nil)
|
116
276
|
end
|
277
|
+
|
278
|
+
it 'with object + array' do
|
279
|
+
obj = { x: [{ y: 2, z: 3 }, { y: 4, z: 5 }] }
|
280
|
+
expect(r.path([:x, 0, :y], obj)).to eq(2)
|
281
|
+
end
|
117
282
|
end
|
118
283
|
|
119
284
|
context '#pick' do
|
@@ -130,6 +295,14 @@ describe Ramda::Object do
|
|
130
295
|
end
|
131
296
|
end
|
132
297
|
|
298
|
+
context '#pick_by' do
|
299
|
+
it 'from docs' do
|
300
|
+
is_upper_case = ->(_, key) { key.upcase == key }
|
301
|
+
expect(r.pick_by(is_upper_case, 'a' => 1, 'b' => 2, 'A' => 3, 'B' => 4))
|
302
|
+
.to eq('A' => 3, 'B' => 4)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
133
306
|
context '#project' do
|
134
307
|
it 'from docs' do
|
135
308
|
abby = { name: 'Abby', age: 7, hair: 'blond', grade: 2 }
|
data/spec/ramda/relation_spec.rb
CHANGED
@@ -122,6 +122,17 @@ describe Ramda::Relation do
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
+
context '#max_by' do
|
126
|
+
it 'from docs' do
|
127
|
+
square = ->(n) { n * n; }
|
128
|
+
|
129
|
+
expect(r.max_by(square, -3, 2)).to eq(-3)
|
130
|
+
|
131
|
+
expect(R.reduce(r.max_by(square), 0, [3, -5, 4, 1, -2])).to eq(-5)
|
132
|
+
expect(R.reduce(r.max_by(square), 0, [])).to eq(0)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
125
136
|
context '#min' do
|
126
137
|
it 'from docs' do
|
127
138
|
expect(r.min(789, 123)).to be(123)
|
@@ -129,6 +140,17 @@ describe Ramda::Relation do
|
|
129
140
|
end
|
130
141
|
end
|
131
142
|
|
143
|
+
context '#min_by' do
|
144
|
+
it 'from docs' do
|
145
|
+
square = ->(n) { n * n; }
|
146
|
+
|
147
|
+
expect(r.min_by(square, -3, 2)).to eq(2)
|
148
|
+
|
149
|
+
expect(R.reduce(r.min_by(square), 100, [3, -5, 4, 1, -2])).to eq(1)
|
150
|
+
expect(R.reduce(r.min_by(square), 0, [])).to eq(0)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
132
154
|
context '#prop_eq' do
|
133
155
|
it 'from docs' do
|
134
156
|
abby = { name: 'Abby', age: 7, hair: 'blond' }
|
data/spec/ramda/type_spec.rb
CHANGED
@@ -23,4 +23,16 @@ describe Ramda::Type do
|
|
23
23
|
expect(r.is_nil('')).to be_falsey
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
context '#type' do
|
28
|
+
it 'from docs' do
|
29
|
+
expect(r.type({})).to be(Hash)
|
30
|
+
expect(r.type(false)).to be(FalseClass)
|
31
|
+
expect(r.type('s')).to be(String)
|
32
|
+
expect(r.type(nil)).to be(NilClass)
|
33
|
+
expect(r.type([])).to be(Array)
|
34
|
+
expect(r.type(/[A-z]/)).to be(Regexp)
|
35
|
+
expect(r.type(-> {})).to be(Proc)
|
36
|
+
end
|
37
|
+
end
|
26
38
|
end
|
data/spec/ramda_spec.rb
CHANGED
@@ -25,6 +25,7 @@ describe Ramda do
|
|
25
25
|
r(:append)
|
26
26
|
r(:apply)
|
27
27
|
r(:assoc)
|
28
|
+
r(:assoc_path)
|
28
29
|
r(:binary)
|
29
30
|
r(:bind)
|
30
31
|
r(:chain)
|
@@ -82,6 +83,10 @@ describe Ramda do
|
|
82
83
|
r(:last)
|
83
84
|
r(:last_index_of)
|
84
85
|
r(:length)
|
86
|
+
r(:lens)
|
87
|
+
r(:lens_index)
|
88
|
+
r(:lens_path)
|
89
|
+
r(:lens_prop)
|
85
90
|
r(:lift)
|
86
91
|
r(:lift_n)
|
87
92
|
r(:lt)
|
@@ -89,23 +94,28 @@ describe Ramda do
|
|
89
94
|
r(:map)
|
90
95
|
r(:match)
|
91
96
|
r(:max)
|
97
|
+
r(:max_by)
|
92
98
|
r(:memoize)
|
93
99
|
r(:merge)
|
94
100
|
r(:min)
|
101
|
+
r(:min_by)
|
95
102
|
r(:modulo)
|
96
103
|
r(:multiply)
|
97
104
|
r(:n_ary)
|
105
|
+
r(:negate)
|
98
106
|
r(:not)
|
99
107
|
r(:nth)
|
100
108
|
r(:of)
|
101
109
|
r(:omit)
|
102
110
|
r(:once)
|
103
111
|
r(:or)
|
112
|
+
r(:over)
|
104
113
|
r(:partition)
|
105
114
|
r(:path)
|
106
115
|
r(:path_eq)
|
107
116
|
r(:pick)
|
108
117
|
r(:pick_all)
|
118
|
+
r(:pick_by)
|
109
119
|
r(:pipe)
|
110
120
|
r(:pluck)
|
111
121
|
r(:prepend)
|
@@ -123,6 +133,7 @@ describe Ramda do
|
|
123
133
|
r(:repeat)
|
124
134
|
r(:replace)
|
125
135
|
r(:reverse)
|
136
|
+
r(:set)
|
126
137
|
r(:slice)
|
127
138
|
r(:sort)
|
128
139
|
r(:sort_by)
|
@@ -138,14 +149,18 @@ describe Ramda do
|
|
138
149
|
r(:to_pairs)
|
139
150
|
r(:to_upper)
|
140
151
|
r(:trim)
|
152
|
+
r(:type)
|
153
|
+
r(:unapply)
|
141
154
|
r(:unary)
|
142
155
|
r(:union)
|
143
156
|
r(:union_with)
|
144
157
|
r(:uniq)
|
145
158
|
r(:uniq_with)
|
146
159
|
r(:unnest)
|
160
|
+
r(:update)
|
147
161
|
r(:use_with)
|
148
162
|
r(:values)
|
163
|
+
r(:view)
|
149
164
|
r(:where)
|
150
165
|
r(:xprod)
|
151
166
|
r(:zip)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ramda-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vadim Lazebny
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby version of Ramda Js library.
|
14
14
|
email:
|
@@ -31,6 +31,7 @@ files:
|
|
31
31
|
- lib/ramda/function.rb
|
32
32
|
- lib/ramda/internal/curried_method.rb
|
33
33
|
- lib/ramda/internal/function_with_arity.rb
|
34
|
+
- lib/ramda/internal/functors.rb
|
34
35
|
- lib/ramda/list.rb
|
35
36
|
- lib/ramda/logic.rb
|
36
37
|
- lib/ramda/math.rb
|