jgomo3-func 0.1.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.mailmap +1 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +0 -4
- data/Gemfile.lock +1 -1
- data/README.md +4 -0
- data/changelogs/releases/1.0.0.md +10 -0
- data/changelogs/releases/1.0.1.md +5 -0
- data/jgomo3-func.gemspec +5 -0
- data/lib/jgomo3/func/core_ext/object.rb +38 -17
- data/lib/jgomo3/func/version.rb +1 -1
- data/todo.org +86 -0
- metadata +64 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9f0b16949f99318dbcb8a0439d9c441178b7858bc6c341be8a86e4b2c52e64e
|
4
|
+
data.tar.gz: c982c140130a959f36b2fc3e93a228bea440a648938c8ba430d24d11a6c01e1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c92f1538e10821e7101510372b23886b59d351da6bfb49ab70794657f022867d9300d9504fdb83b7c2638b9777341142d8b807fbb7bd6a76170462ac9343b7a0
|
7
|
+
data.tar.gz: 74d4541b3fefe3aba9cc95b3dd5321d1f6902e2527f878513ea46bbab5b9022cb55281c4fdf3a3a2c7bcaeb2a671cb6f7821d6d2521f8fb96e65b807dd7f6edd
|
data/.mailmap
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Jesús Gómez <jgomo3@gmail.com>
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file.
|
|
3
3
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
4
4
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
5
5
|
|
6
|
+
## 1.0.1 - 2023-04-07
|
7
|
+
### Fixed
|
8
|
+
- Bump the number just to force use of new artifact from Rubygems. I made a mistake publishing the previous version
|
9
|
+
|
10
|
+
---
|
11
|
+
## 1.0.0 - 2023-04-07
|
12
|
+
### Changed
|
13
|
+
- `then_if` accept non callable values and interpret them by their truth value
|
14
|
+
- `then_unless` accept non callable values and interpret them by their truth value
|
15
|
+
- `complement` will negate the receiver's values directly if it is not a callable
|
16
|
+
|
17
|
+
### Removed
|
18
|
+
- `complement` doesn't rais an ArgumentError when it's receiver was not a callable
|
19
|
+
|
20
|
+
---
|
6
21
|
## 0.1.0 - 2022-11-15
|
7
22
|
### Added
|
8
23
|
- Object extensions
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
## 1.0.0 - 2023-04-07
|
2
|
+
### Changed
|
3
|
+
- `then_if` accept non callable values and interpret them by their truth value
|
4
|
+
- `then_unless` accept non callable values and interpret them by their truth value
|
5
|
+
- `complement` will negate the receiver's values directly if it is not a callable
|
6
|
+
|
7
|
+
### Removed
|
8
|
+
- `complement` doesn't rais an ArgumentError when it's receiver was not a callable
|
9
|
+
|
10
|
+
---
|
data/jgomo3-func.gemspec
CHANGED
@@ -26,4 +26,9 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.bindir = "exe"
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
28
|
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_development_dependency "codelog"
|
31
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
32
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
33
|
+
spec.add_development_dependency 'yard'
|
29
34
|
end
|
@@ -10,49 +10,70 @@ class Object
|
|
10
10
|
Proc.new { self }
|
11
11
|
end
|
12
12
|
|
13
|
-
#
|
14
|
-
# callable object.
|
13
|
+
# If the receiver object is callabale, returns a Proc which negates
|
14
|
+
# the result of calling the argumented callable object.
|
15
|
+
#
|
16
|
+
# If it is not a callable, it returns it's negated value
|
15
17
|
#
|
16
18
|
# :positive?.complement.call(1) => false
|
17
19
|
# :nil?.complement.call(nil) => false
|
20
|
+
# false.complement => true
|
18
21
|
def complement
|
19
22
|
callable = case
|
20
23
|
when respond_to?(:call)
|
21
24
|
self
|
22
|
-
|
25
|
+
when respond_to?(:to_proc)
|
23
26
|
self.to_proc
|
24
27
|
end
|
25
|
-
|
26
|
-
|
27
|
-
case error.name
|
28
|
-
when :to_proc
|
29
|
-
raise ArgumentError, "Object is not 'Callable' so it can't have a complement function", caller
|
28
|
+
if callable
|
29
|
+
->(*args, **kwargs, &blk) { !callable.call(*args, **kwargs, &blk) }
|
30
30
|
else
|
31
|
-
|
31
|
+
!self
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
# Applies the given block to the object if the
|
35
|
+
# Applies the given block to the object if the criteria applied on
|
36
36
|
# it holds true. If not, it defaults to the object as if `then_if`
|
37
37
|
# was not called.
|
38
38
|
#
|
39
|
+
# The criteria can be a callable predicate, in which case the
|
40
|
+
# criteria is evaluated with the object as argument. It not, then
|
41
|
+
# the criteria will be interpreted by it's truth value.
|
42
|
+
#
|
39
43
|
# +1.then_if(:positive?) { _1 * 1000 } => 1_000
|
40
44
|
# -1.then_if(:positive?) { _1 * 1000 } => -1
|
41
|
-
|
42
|
-
|
45
|
+
# +1.then_if(true) { _1 * 1000 } => 1_000
|
46
|
+
# +1.then_if(false) { _1 * 1000 } => 1
|
47
|
+
def then_if(criteria)
|
48
|
+
callable = case
|
49
|
+
when criteria.respond_to?(:call)
|
50
|
+
criteria
|
51
|
+
when criteria.respond_to?(:to_proc)
|
52
|
+
criteria.to_proc
|
53
|
+
end
|
54
|
+
|
55
|
+
condition = callable ? callable.call(self) : criteria
|
56
|
+
|
57
|
+
if condition
|
43
58
|
yield self
|
44
59
|
else
|
45
60
|
self
|
46
61
|
end
|
47
62
|
end
|
48
63
|
|
49
|
-
# Applies the given block to the object if the
|
64
|
+
# Applies the given block to the object if the criteria applied on
|
50
65
|
# it doesn't hold true. If not, it defaults to the object as if
|
51
66
|
# `then_unless` was not called.
|
52
67
|
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
|
56
|
-
|
68
|
+
# The criteria can be a callable predicate, in which case the
|
69
|
+
# criteria is evaluated with the object as argument. It not, then
|
70
|
+
# the criteria will be interpreted by it's truth value.
|
71
|
+
#
|
72
|
+
# +1.then_unless(:positive?) { _1 * 1000 } => 1
|
73
|
+
# -1.then_unless(:positive?) { _1 * 1000 } => -1_000
|
74
|
+
# +1.then_unless(false) { _1 * 1000 } => 1_000
|
75
|
+
# +1.then_unless(true) { _1 * 1000 } => 1
|
76
|
+
def then_unless(criteria, &block)
|
77
|
+
then_if(criteria.complement, &block)
|
57
78
|
end
|
58
79
|
end
|
data/lib/jgomo3/func/version.rb
CHANGED
data/todo.org
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
#+title: Potential changes
|
2
|
+
#+author: Jesús Gómez <jgomo3@gmail.com>
|
3
|
+
* TODO Define alias yield_self_if of then_if (and for unless case too)
|
4
|
+
* TODO Explain in API and README that for cases with both ~if~ and ~else~ clauses, it is better to just avoid these functions
|
5
|
+
* TODO Define nil_if and nil_unless
|
6
|
+
For the pattern ~object.then_if(condition){ nil }~, this could be used
|
7
|
+
instead: ~object.nil_if(condition)~.
|
8
|
+
|
9
|
+
This pattern appears when chaining with the "safe navigation operator" (&.). E.g:
|
10
|
+
|
11
|
+
#+begin_ruby
|
12
|
+
object.tx_1.nil_if(condition)&.tx_2&._&._&.tx_3
|
13
|
+
#+end_ruby
|
14
|
+
* TODO Define map_if and map_unless
|
15
|
+
Applies the block to the processed element only if the condition is
|
16
|
+
true.
|
17
|
+
|
18
|
+
~data.map_if(condition){ f(_1) }~ would be equivalent to:
|
19
|
+
|
20
|
+
#+begin_ruby
|
21
|
+
data.map{ condition(_1) ? f(_1) : _1 }
|
22
|
+
#+end_ruby
|
23
|
+
|
24
|
+
Not the same to neither of the following patterns:
|
25
|
+
|
26
|
+
#+begin_ruby
|
27
|
+
data.filter{ condition(_1) }.map{ f_1 }
|
28
|
+
data.map{ f_1 }.filter{ condition(_1) }
|
29
|
+
#+end_ruby
|
30
|
+
|
31
|
+
~map_if~ and ~map~ will produce collection of the same
|
32
|
+
cardinality. ~filter{}.map{}~ or ~map{}.filter{}~ can produce
|
33
|
+
collection with lower cardinality of ~map~.
|
34
|
+
|
35
|
+
* TODO Define each_if and each_unless
|
36
|
+
In the same spirit as the other functions of this gem,
|
37
|
+
~data.each_if(condition) { f(_1) }~ should be the same as:
|
38
|
+
|
39
|
+
#+begin_ruby
|
40
|
+
data.each do
|
41
|
+
if condition(_1)
|
42
|
+
f(_1)
|
43
|
+
else
|
44
|
+
_1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
#+end_ruby
|
48
|
+
|
49
|
+
It should also support the other forms of ~each~ where it receives
|
50
|
+
arguments that will be "appended" to the enumerator call, and the form
|
51
|
+
where it doesn't receive nor arguments neither block.
|
52
|
+
|
53
|
+
In all cases, it should be in a way that "makes sense".
|
54
|
+
|
55
|
+
* TODO Define tap_if and tap_unless
|
56
|
+
|
57
|
+
This one is the easiest to "understand" as it can be read as "make
|
58
|
+
side effect if ...".
|
59
|
+
|
60
|
+
* TODO Merge procer default to_proc implementation as an explicit call
|
61
|
+
|
62
|
+
[[../procer/ge][../proce.gemspec]] defines a default =to_proc= to all objects. If you
|
63
|
+
don't want to add that behaviour to your system, you can use this
|
64
|
+
proposed method to explicitly as for the default procer propose.
|
65
|
+
|
66
|
+
The idea... With procer, you can do:
|
67
|
+
|
68
|
+
#+begin_ruby
|
69
|
+
['1', 2, 3 '4', '5'].filter(&Numeric) # => [2, 3]
|
70
|
+
#+end_ruby
|
71
|
+
|
72
|
+
Because *procer* defines a default ~to_proc~ method for classes, which
|
73
|
+
is to compare the class with it's argument using the "Case Equality
|
74
|
+
(~===~)" operator.
|
75
|
+
|
76
|
+
But without procer, this new method, let's say it is called =procer=,
|
77
|
+
we could do:
|
78
|
+
|
79
|
+
#+begin_ruby
|
80
|
+
# Option 1
|
81
|
+
['1', 2, 3 '4', '5'].filter(&procer(Numeric)) # => [2, 3]
|
82
|
+
|
83
|
+
# Option 2
|
84
|
+
['1', 2, 3 '4', '5'].filter(&Numeric.procer) # => [2, 3]
|
85
|
+
#+end_ruby
|
86
|
+
|
metadata
CHANGED
@@ -1,15 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jgomo3-func
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jesús Gómez
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2023-04-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: codelog
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '12.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '12.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
13
69
|
description:
|
14
70
|
email:
|
15
71
|
- jgomo3@gmail.com
|
@@ -18,6 +74,7 @@ extensions: []
|
|
18
74
|
extra_rdoc_files: []
|
19
75
|
files:
|
20
76
|
- ".gitignore"
|
77
|
+
- ".mailmap"
|
21
78
|
- ".rspec"
|
22
79
|
- ".travis.yml"
|
23
80
|
- CHANGELOG.md
|
@@ -33,12 +90,15 @@ files:
|
|
33
90
|
- changelogs/header.txt
|
34
91
|
- changelogs/releases/.gitkeep
|
35
92
|
- changelogs/releases/0.1.0.md
|
93
|
+
- changelogs/releases/1.0.0.md
|
94
|
+
- changelogs/releases/1.0.1.md
|
36
95
|
- changelogs/template.yml
|
37
96
|
- changelogs/unreleased/.gitkeep
|
38
97
|
- jgomo3-func.gemspec
|
39
98
|
- lib/jgomo3/func.rb
|
40
99
|
- lib/jgomo3/func/core_ext/object.rb
|
41
100
|
- lib/jgomo3/func/version.rb
|
101
|
+
- todo.org
|
42
102
|
homepage: https://github.com/jgomo3/jgomo3-func
|
43
103
|
licenses:
|
44
104
|
- MIT
|
@@ -61,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
61
121
|
- !ruby/object:Gem::Version
|
62
122
|
version: '0'
|
63
123
|
requirements: []
|
64
|
-
rubygems_version: 3.
|
124
|
+
rubygems_version: 3.1.4
|
65
125
|
signing_key:
|
66
126
|
specification_version: 4
|
67
127
|
summary: Library of functions I find useful enough to be included always
|