jgomo3-func 0.1.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b6cfecdff107f74516b252a00057ff4490239b21d3ca56eead0e75d1448ffef
4
- data.tar.gz: a6e22e6ad37289340d286dd27e297d5a0a1c259f216a7257005084995d7f79f7
3
+ metadata.gz: a9f0b16949f99318dbcb8a0439d9c441178b7858bc6c341be8a86e4b2c52e64e
4
+ data.tar.gz: c982c140130a959f36b2fc3e93a228bea440a648938c8ba430d24d11a6c01e1c
5
5
  SHA512:
6
- metadata.gz: 8019ec224ad628cb8a3696a2e42e1b09a0fbffdf12f7a54f33d0157a425beb04028d7262c78361639016201c741a30d6332376b7470a24034a9ebf1bde6c91c0
7
- data.tar.gz: 721de13bbbcde4d5fadeac3e05109718e6c1ef65e751df13ea4369005ea0903da9181908c08a0599e3a84fe6b9ce98185372df7846d2b8457f1d46f2ed37d69f
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
@@ -3,7 +3,3 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in jgomo3-func.gemspec
4
4
  gemspec
5
5
 
6
- gem 'codelog'
7
- gem "rake", "~> 12.0"
8
- gem "rspec", "~> 3.0"
9
- gem 'yard'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jgomo3-func (0.1.0)
4
+ jgomo3-func (1.0.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -3,6 +3,10 @@
3
3
  By requiring this Gem, some extensions will be applied to Ruby core
4
4
  classes (similar to what Activesupport does).
5
5
 
6
+ ```
7
+ require 'jgomo3/func'
8
+ ```
9
+
6
10
  The extensions is a collection of methods I find useful for any
7
11
  project. This is a quick list:
8
12
 
@@ -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
+ ---
@@ -0,0 +1,5 @@
1
+ ## 1.0.1 - 2023-04-07
2
+ ### Fixed
3
+ - Bump the number just to force use of new artifact from Rubygems. I made a mistake publishing the previous version
4
+
5
+ ---
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
- # Returns a Proc which negates the result of calling the argumented
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
- else
25
+ when respond_to?(:to_proc)
23
26
  self.to_proc
24
27
  end
25
- ->(*args, **kwargs, &blk) { !callable.call(*args, **kwargs, &blk) }
26
- rescue NoMethodError => error
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
- raise
31
+ !self
32
32
  end
33
33
  end
34
34
 
35
- # Applies the given block to the object if the condition applied on
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
- def then_if(condition)
42
- if condition.to_proc.call(self)
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 condition applied on
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
- # +1.then_if(:positive?) { _1 * 1000 } => 1_000
54
- # -1.then_if(:positive?) { _1 * 1000 } => -1
55
- def then_unless(condition, &block)
56
- then_if(condition.complement, &block)
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
@@ -1,5 +1,5 @@
1
1
  module Jgomo3
2
2
  module Func
3
- VERSION = "0.1.0"
3
+ VERSION = "1.0.1"
4
4
  end
5
5
  end
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.0
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: 2022-11-15 00:00:00.000000000 Z
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.3.7
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