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 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