ramda-ruby 0.8.1 → 0.9.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.
@@ -5,17 +5,19 @@ module Ramda
5
5
  # Curried Method
6
6
  module CurriedMethod
7
7
  def curried_method(name, &block)
8
- define_singleton_method(name, &curried_method_body(name, block.arity, &block))
8
+ define_method(name, &curried_method_body(name, block.arity, &block))
9
9
  end
10
10
 
11
11
  # rubocop:disable Metrics/MethodLength
12
12
  def curried_method_body(name, arity, &block)
13
- Ramda::Internal::FunctionWithArity.new.call(arity) do |*args|
13
+ Ramda::Internal::FunctionWithArity.call(arity) do |*args|
14
14
  begin
15
- if args.include?(Ramda.__)
15
+ if args.index(Ramda.__)
16
16
  replace_placeholder(args, &block).curry
17
17
  else
18
- args.empty? ? block : yield(*args)
18
+ result = args.empty? ? block : yield(*args)
19
+ debug_log(name, args, result) if ::Ramda::DEBUG_MODE
20
+ result
19
21
  end
20
22
  rescue StandardError => e
21
23
  ::Ramda.exception_handler.call(e, name)
@@ -25,62 +27,17 @@ module Ramda
25
27
  # rubocop:enable Metrics/MethodLength
26
28
 
27
29
  def replace_placeholder(basic_args)
28
- Ramda::Internal::FunctionWithArity.new.call(basic_args.count(Ramda.__)) do |*new_args|
30
+ Ramda::Internal::FunctionWithArity.call(basic_args.count(Ramda.__)) do |*new_args|
29
31
  cloned_args = basic_args.dup
30
32
  new_args.each { |arg| cloned_args[cloned_args.index(Ramda.__)] = arg }
31
- yield(*cloned_args)
33
+ result = yield(*cloned_args)
34
+ debug_log(name, cloned_args, result) if ::Ramda::DEBUG_MODE
35
+ result
32
36
  end
33
37
  end
34
38
 
35
- def curried_method_v2(name, &block)
36
- fn = Ramda::Internal::FunctionWithArity.new.call(block.arity) do |*args|
37
- if args.empty?
38
- block
39
- else
40
- yield(*args)
41
- end
42
- end
43
-
44
- define_singleton_method(name, &fn.curry)
45
- end
46
-
47
- def curried_method_v1(name, &block)
48
- define_singleton_method(name) do |*args|
49
- curried = block.curry
50
- # curried.define_singleton_method(:origin_arity) { block.arity }
51
-
52
- return curried if args.empty?
53
-
54
- curried.call(*args)
55
- end
56
- end
57
-
58
- if RUBY_PLATFORM == 'java'
59
- # This hack resolved issue:
60
- # undefined method `__make_curry_proc__' for Ramda::Math:Module
61
- #
62
- # Source:
63
- # https://github.com/jruby/jruby/issues/1523
64
- #
65
- # rubocop:disable Metrics/MethodLength
66
- def __make_curry_proc__(proc, passed, arity)
67
- is_lambda = proc.lambda?
68
- passed.freeze
69
-
70
- __send__((is_lambda ? :lambda : :proc)) do |*argv, &passed_proc|
71
- my_passed = passed + argv
72
- # original
73
- # if my_passed.length < arity
74
- # changed
75
- if my_passed.length < arity.abs - 1
76
- warn "#{caller[0]}: given block not used" unless passed_proc.nil?
77
- __make_curry_proc__(proc, my_passed, arity)
78
- else
79
- proc.call(*my_passed)
80
- end
81
- end
82
- end
83
- # rubocop:enable Metrics/MethodLength
39
+ def debug_log(name, args, result)
40
+ puts "-> #{name}(#{args.join(', ')}) # #{result}"
84
41
  end
85
42
  end
86
43
  end
@@ -1,11 +1,11 @@
1
1
  module Ramda
2
2
  module Internal
3
3
  # Curried Method
4
- class FunctionWithArity
4
+ module FunctionWithArity
5
5
  # rubocop:disable Metrics/CyclomaticComplexity
6
6
  # rubocop:disable Metrics/MethodLength
7
7
  # rubocop:disable Metrics/ParameterLists
8
- def call(arity)
8
+ def self.call(arity)
9
9
  case arity
10
10
  when 0, -1
11
11
  ->(*a) { yield(*a) }
@@ -0,0 +1,33 @@
1
+ module Ramda
2
+ module Internal
3
+ module Java
4
+ # This hack resolved issue:
5
+ # undefined method `__make_curry_proc__' for Ramda::Math:Module
6
+ #
7
+ # Source:
8
+ # https://github.com/jruby/jruby/issues/1523
9
+ #
10
+ module MakeCurryProc
11
+ # rubocop:disable Metrics/MethodLength
12
+ def __make_curry_proc__(proc, passed, arity)
13
+ is_lambda = proc.lambda?
14
+ passed.freeze
15
+
16
+ __send__((is_lambda ? :lambda : :proc)) do |*argv, &passed_proc|
17
+ my_passed = passed + argv
18
+ # original
19
+ # if my_passed.length < arity
20
+ # changed
21
+ if my_passed.length < arity.abs - 1
22
+ warn "#{caller[0]}: given block not used" unless passed_proc.nil?
23
+ __make_curry_proc__(proc, my_passed, arity)
24
+ else
25
+ proc.call(*my_passed)
26
+ end
27
+ end
28
+ end
29
+ # rubocop:enable Metrics/MethodLength
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/ramda/list.rb CHANGED
@@ -97,6 +97,22 @@ module Ramda
97
97
  end
98
98
  end
99
99
 
100
+ # Returns a new list excluding the leading elements of a given list which
101
+ # satisfy the supplied predicate function. It passes each value to the
102
+ # supplied predicate function, skipping elements while the predicate
103
+ # function returns true. The predicate function is applied
104
+ # to one argument: (value).
105
+ #
106
+ # Dispatches to the dropWhile method of the second argument, if present.
107
+ #
108
+ # Acts as a transducer if a transformer is given in list position.
109
+ #
110
+ # (a -> Boolean) -> [a] -> [a]
111
+ #
112
+ curried_method(:drop_while) do |fn, xs|
113
+ xs.drop_while(&fn)
114
+ end
115
+
100
116
  # Takes a predicate and a Filterable, and returns a new filterable of the same
101
117
  # type containing the members of the given filterable which satisfy the given
102
118
  # predicate. Filterable objects include plain objects or any object that
@@ -210,6 +226,15 @@ module Ramda
210
226
  xs.index(x)
211
227
  end
212
228
 
229
+ # Returns all but the last element of the given list or string.
230
+ #
231
+ # [a] -> [a]
232
+ # String -> String
233
+ #
234
+ curried_method(:init) do |xs|
235
+ xs[0..-2]
236
+ end
237
+
213
238
  # Inserts the supplied element into the list, at the specified index.
214
239
  # Note that this is not destructive: it returns a copy of the list with
215
240
  # the changes. No lists have been harmed in the application of this function.
@@ -220,6 +245,16 @@ module Ramda
220
245
  xs.dup.insert(idx, x)
221
246
  end
222
247
 
248
+ # Inserts the sub-list into the list, at the specified index.
249
+ # Note that this is not destructive: it returns a copy of the list
250
+ # with the changes. No lists have been harmed in the application of this function.
251
+ #
252
+ # Number -> [a] -> [a] -> [a]
253
+ #
254
+ curried_method(:insert_all) do |index, elts, xs|
255
+ xs.dup.insert(index, *elts)
256
+ end
257
+
223
258
  # Returns a string made by inserting the separator between each element and
224
259
  # concatenating all the elements into a single string.
225
260
  #
@@ -301,7 +336,7 @@ module Ramda
301
336
  # Filterable f => (a -> Boolean) -> f a -> [f a, f a]
302
337
  #
303
338
  curried_method(:partition) do |fn, xs|
304
- ::Ramda.juxt([filter, reject]).call(fn, xs)
339
+ ::Ramda.juxt([::Ramda.filter, ::Ramda.reject]).call(fn, xs)
305
340
  end
306
341
 
307
342
  # Returns a new list by plucking the same named property off all objects
@@ -425,7 +460,7 @@ module Ramda
425
460
  # String -> String
426
461
  #
427
462
  curried_method(:tail) do |xs|
428
- drop(1, xs)
463
+ ::Ramda.drop(1, xs)
429
464
  end
430
465
 
431
466
  # Returns the first n elements of the given list, string.
@@ -478,7 +513,7 @@ module Ramda
478
513
  # Chain c => c (c a) -> c a
479
514
  #
480
515
  curried_method(:unnest) do |xs|
481
- Ramda.chain(Ramda.identity, xs)
516
+ ::Ramda.chain(::Ramda.identity, xs)
482
517
  end
483
518
 
484
519
  # Returns a new copy of the array with the element at the provided
data/lib/ramda/logic.rb CHANGED
@@ -26,7 +26,7 @@ module Ramda
26
26
  # (*... -> *) -> (*... -> Boolean)
27
27
  #
28
28
  curried_method(:complement) do |fn|
29
- ::Ramda::Internal::FunctionWithArity.new.call(fn.arity) do |*args|
29
+ ::Ramda::Internal::FunctionWithArity.call(fn.arity) do |*args|
30
30
  !fn.call(*args)
31
31
  end.curry
32
32
  end
data/lib/ramda/object.rb CHANGED
@@ -33,7 +33,7 @@ module Ramda
33
33
  if path.empty?
34
34
  val
35
35
  else
36
- cloned = clone(obj)
36
+ cloned = ::Ramda.clone(obj)
37
37
  path[0...-1].reduce(cloned) do |acc, k|
38
38
  case acc[k]
39
39
  when Hash, Array
@@ -56,10 +56,10 @@ module Ramda
56
56
  case obj
57
57
  when Hash
58
58
  obj.each_with_object(obj.dup) do |(key, value), acc|
59
- acc[clone(key)] = clone(value)
59
+ acc[::Ramda.clone(key)] = ::Ramda.clone(value)
60
60
  end
61
61
  when Array
62
- obj.map(&clone)
62
+ obj.map(&::Ramda.clone)
63
63
  when Symbol, Integer, NilClass, TrueClass, FalseClass
64
64
  obj
65
65
  else
@@ -72,7 +72,7 @@ module Ramda
72
72
  # String -> {k: v} -> {k: v}
73
73
  #
74
74
  curried_method(:dissoc) do |prop, obj|
75
- clone(obj).tap { |o| o.delete(prop) }
75
+ ::Ramda.clone(obj).tap { |o| o.delete(prop) }
76
76
  end
77
77
 
78
78
  # Returns whether or not an object has an own property with the specified name
@@ -101,6 +101,56 @@ module Ramda
101
101
  a[prop] == b[prop]
102
102
  end
103
103
 
104
+ # Creates a new object by recursively evolving a shallow copy of object,
105
+ # according to the transformation functions. All non-primitive properties
106
+ # are copied by reference.
107
+ #
108
+ # A transformation function will not be invoked if its corresponding
109
+ # key does not exist in the evolved object.
110
+ #
111
+ # {k: (v -> v)} -> {k: v} -> {k: v}
112
+ #
113
+ curried_method(:evolve) do |trans, obj|
114
+ obj.each_with_object({}) do |(key, val), acc|
115
+ acc[key] = case trans[key]
116
+ when Hash
117
+ ::Ramda.evolve(trans[key], val)
118
+ when Proc
119
+ trans[key].call(val)
120
+ else
121
+ val
122
+ end
123
+ end
124
+ end
125
+
126
+ # Same as R.invertObj, however this accounts for objects with duplicate
127
+ # values by putting the values into an array.
128
+ #
129
+ # {s: x} -> {x: [ s, ...]}
130
+ #
131
+ curried_method(:invert) do |obj|
132
+ case obj
133
+ when Hash
134
+ # Ramda.map(Ramda.map(:first.to_proc), obj.group_by { |_, v| v })
135
+ Hash[obj.group_by { |_, v| v }.map { |k, v| [k, v.map(&:first)] }]
136
+ when Array
137
+ Hash[obj.each_with_index.group_by { |v, _| v }.map { |k, v| [k, v.map(&:last)] }]
138
+ else
139
+ {}
140
+ end
141
+ end
142
+
143
+ curried_method(:invert_obj) do |obj|
144
+ case obj
145
+ when Hash
146
+ obj.invert
147
+ when Array
148
+ Hash[obj.each_with_index.map { |k, v| [k, v] }]
149
+ else
150
+ {}
151
+ end
152
+ end
153
+
104
154
  # Returns a list containing the names of all the enumerable own properties
105
155
  # of the supplied object.
106
156
  # Note that the order of the output array is not guaranteed.
@@ -132,7 +182,7 @@ module Ramda
132
182
  #
133
183
  curried_method(:lens) do |getter, setter|
134
184
  curried_method_body(:lens, 2) do |to_functor_fn, target|
135
- Ramda.map(
185
+ ::Ramda.map(
136
186
  ->(focus) { setter.call(focus, target) },
137
187
  to_functor_fn.call(getter.call(target))
138
188
  )
@@ -145,7 +195,7 @@ module Ramda
145
195
  # Lens s a = Functor f => (a -> f a) -> s -> f s
146
196
  #
147
197
  curried_method(:lens_index) do |n|
148
- lens(Ramda.nth(0), Ramda.update(n))
198
+ ::Ramda.lens(::Ramda.nth(0), ::Ramda.update(n))
149
199
  end
150
200
 
151
201
  # Returns a lens whose focus is the specified path.
@@ -155,7 +205,7 @@ module Ramda
155
205
  # Lens s a = Functor f => (a -> f a) -> s -> f s
156
206
  #
157
207
  curried_method(:lens_path) do |path|
158
- lens(Ramda.path(path), Ramda.assoc_path(path))
208
+ ::Ramda.lens(Ramda.path(path), Ramda.assoc_path(path))
159
209
  end
160
210
 
161
211
  # Returns a lens whose focus is the specified property.
@@ -164,7 +214,17 @@ module Ramda
164
214
  # Lens s a = Functor f => (a -> f a) -> s -> f s
165
215
  #
166
216
  curried_method(:lens_prop) do |k|
167
- lens(Ramda.prop(k), Ramda.assoc(k))
217
+ ::Ramda.lens(Ramda.prop(k), Ramda.assoc(k))
218
+ end
219
+
220
+ # An Object-specific version of map. The function is applied to
221
+ # three arguments: (value, key, obj).
222
+ # If only the value is significant, use map instead.
223
+ #
224
+ # ((*, String, Object) -> *) -> Object -> Object
225
+ #
226
+ curried_method(:map_obj_indexed) do |fn, obj|
227
+ Hash[obj.map { |(k, v)| [k, fn.call(v, k, obj)] }]
168
228
  end
169
229
 
170
230
  # Create a new object with the own properties of the first object merged
@@ -182,7 +242,7 @@ module Ramda
182
242
  # [String] -> {String: *} -> {String: *}
183
243
  #
184
244
  curried_method(:omit) do |keys, obj|
185
- obj_copy = clone(obj)
245
+ obj_copy = ::Ramda.clone(obj)
186
246
  keys.each(&obj_copy.method(:delete))
187
247
  obj_copy
188
248
  end
@@ -244,7 +304,7 @@ module Ramda
244
304
  # [k] -> [{k: v}] -> [{k: v}]
245
305
  #
246
306
  curried_method(:project) do |keys, objs|
247
- objs.map(&pick_all(keys))
307
+ objs.map(&::Ramda.pick_all(keys))
248
308
  end
249
309
 
250
310
  # Returns a function that when supplied an object returns the indicated
@@ -287,7 +347,7 @@ module Ramda
287
347
  # Lens s a = Functor f => (a -> f a) -> s -> f s
288
348
  #
289
349
  curried_method(:set) do |lens, v, x|
290
- over(lens, Ramda.always(v), x)
350
+ ::Ramda.over(lens, Ramda.always(v), x)
291
351
  end
292
352
 
293
353
  # Converts an object into an array of key, value arrays. Only the
data/lib/ramda/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ramda
2
- VERSION = '0.8.1'.freeze
2
+ VERSION = '0.9.0'.freeze
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ramda::Function do
4
- let(:r) { described_class }
4
+ let(:r) { Ramda }
5
5
 
6
6
  context '#F' do
7
7
  it 'from docs' do
@@ -85,6 +85,35 @@ describe Ramda::Function do
85
85
  end
86
86
  end
87
87
 
88
+ context '#call' do
89
+ it 'from docs' do
90
+ indent_n = R.pipe(R.times(R.always(' ')),
91
+ R.join(''),
92
+ R.replace(/^(?!$)/m))
93
+
94
+ format = R.converge(R.call, [
95
+ R.pipe(R.prop(:indent), indent_n),
96
+ R.prop(:value)
97
+ ])
98
+
99
+ expect(format.call(indent: 2, value: "foo\nbar\nbaz\n")).to eq(" foo\n bar\n baz\n")
100
+ end
101
+
102
+ it 'returns the result of calling its first argument with the remaining arguments' do
103
+ fn = ->(*args) { args.max }
104
+ expect(R.call(fn, 1, 2, 3, -99, 42, 6, 7)).to eq(42)
105
+ end
106
+
107
+ it 'accepts one or more arguments' do
108
+ fn = ->(*args) { args.length; }
109
+
110
+ expect(R.call(fn)).to eq(0)
111
+ expect(R.call(fn, 'x')).to eq(1)
112
+ expect(R.call(fn, 'x', 'y')).to eq(2)
113
+ expect(R.call(fn, 'x', 'y', 'z')).to eq(3)
114
+ end
115
+ end
116
+
88
117
  context '#comparator' do
89
118
  it 'from docs' do
90
119
  sort_rule = r.comparator(->(a, b) { a < b })
@@ -355,6 +384,14 @@ describe Ramda::Function do
355
384
  end
356
385
  end
357
386
 
387
+ context '#nth_arg' do
388
+ it 'from docs' do
389
+ expect(R.nth_arg(1, 'a', 'b', 'c')).to eq('b')
390
+ expect(R.nth_arg(1).call('a', 'b', 'c')).to eq('b')
391
+ expect(R.nth_arg(-1).call('a', 'b', 'c')).to eq('c')
392
+ end
393
+ end
394
+
358
395
  context '#of' do
359
396
  it 'from docs' do
360
397
  expect(r.of(nil)).to eq([nil])