comp 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c927bf75c65fbbeefc7e80590410d970d096b9c
4
+ data.tar.gz: ba154301fd04d8b571b896adbd54ea558426085d
5
+ SHA512:
6
+ metadata.gz: 96523e9652f384276d8e25291f09c0fcbcaf8b25d7b5dc46f6502d3d5a00be4587c1f58eb3f173932ab4810461726f06efcf030c5da1e36207bd270889aea182
7
+ data.tar.gz: bce2078f4a9f14a3f14af05309b513100df143918dc40b28d19040546db4b60748d43a593f8c865882acdec83b9a5e58da4dbe6e013411ca91f3a8e4e50f26f9
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Paul Mucur
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,99 @@
1
+ # comp [![Build Status](https://travis-ci.org/mudge/comp.svg?branch=master)](https://travis-ci.org/mudge/comp)
2
+
3
+ A Ruby library to add [function
4
+ composition](https://en.wikipedia.org/wiki/Function_composition) to
5
+ [`Proc`s](http://ruby-doc.org/core/Proc.html) (including `lambda`s) and
6
+ [`Method`s](http://ruby-doc.org/core/Method.html).
7
+
8
+ **Current version:** 1.0.0
9
+ **Supported Ruby versions:** 1.9.2, 1.9.3, 2.0, 2.1, 2.2
10
+
11
+ ## Installation
12
+
13
+ ```
14
+ gem install comp -v '~> 1.0'
15
+ ```
16
+
17
+ Or, in your `Gemfile`:
18
+
19
+ ```ruby
20
+ gem 'comp', '~> 1.0'
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```ruby
26
+ require 'comp'
27
+
28
+ # Basic usage
29
+ add = proc { |x, y| x + y }
30
+ double = proc { |x| x * 2 }
31
+ double_after_add = double * add
32
+
33
+ double_after_add.call(1, 2)
34
+ #=> 6
35
+
36
+ # Composing Procs and other callables
37
+ class Parser
38
+ def call(json)
39
+ JSON.load(json)
40
+ end
41
+ end
42
+
43
+ extract_name = proc { |attributes| attributes.fetch('name') }
44
+ (extract_name * Parser.new).call('{"name": "Alice"}')
45
+ #=> "Alice"
46
+ ```
47
+
48
+ Requiring `comp` will require two files:
49
+
50
+ * `comp/proc`: add [`Proc#*`](#proc) if it hasn't already been defined;
51
+ * `comp/method`: add [`Method#*`](#method) if it hasn't already been defined.
52
+
53
+ ## API Documentation
54
+
55
+ ### `Proc#*`
56
+
57
+ ```ruby
58
+ increment_and_add = proc { |x| x * 2 } * proc { |x| x + 1 }
59
+ increment_and_add.call(1)
60
+ #=> 4
61
+ ```
62
+
63
+ Composes a `Proc` (`f`) with any object that responds to `call` (`g`) returning
64
+ a new `Proc` which will call `g` with any given arguments (including blocks)
65
+ and then call `f` with the result.
66
+
67
+ If `f` was created with `lambda`, the resulting `Proc` will also be a
68
+ `lambda`.
69
+
70
+ ### `Method#*`
71
+
72
+ ```ruby
73
+ class Number
74
+ def add(x, y)
75
+ x + y
76
+ end
77
+
78
+ def double(x)
79
+ x * 2
80
+ end
81
+ end
82
+
83
+ (number.new.method(:double) * number.new.method(:add)).call(2, 3)
84
+ #=> 10
85
+ ```
86
+
87
+ Composes a `Method` (`f`) with any object that responds to `call` (`g`)
88
+ returning a new `Proc` which will call `g` with any given arguments (including
89
+ blocks) and then call `f` with the result.
90
+
91
+ ## Why isn't this in Ruby itself?
92
+
93
+ Good question: I'd like to [change](https://bugs.ruby-lang.org/issues/6284) [that](https://github.com/ruby/ruby/pull/935).
94
+
95
+ ## License
96
+
97
+ Copyright © 2015 Paul Mucur.
98
+
99
+ Distributed under the MIT License.
@@ -0,0 +1,2 @@
1
+ require 'comp/proc'
2
+ require 'comp/method'
@@ -0,0 +1,9 @@
1
+ require 'comp/proc'
2
+
3
+ class Method
4
+ unless method_defined?(:*)
5
+ def *(g)
6
+ to_proc * g
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class Proc
2
+ unless method_defined?(:*)
3
+ def *(g)
4
+ if lambda?
5
+ lambda { |*args, &blk| call(g.call(*args, &blk)) }
6
+ else
7
+ proc { |*args, &blk| call(g.call(*args, &blk)) }
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,74 @@
1
+ require 'comp/method'
2
+
3
+ RSpec.describe Method do
4
+ describe '#*' do
5
+ it 'composes two Methods together' do
6
+ number = Class.new do
7
+ def increment(x)
8
+ x + 1
9
+ end
10
+
11
+ def double(x)
12
+ x * 2
13
+ end
14
+ end
15
+ increment = number.new.method(:increment)
16
+ double = number.new.method(:double)
17
+ increment_and_double = double * increment
18
+
19
+ expect(increment_and_double.call(1)).to eq(4)
20
+ end
21
+
22
+ it 'passes multiple arguments to g' do
23
+ number = Class.new do
24
+ def add(x, y)
25
+ x + y
26
+ end
27
+
28
+ def double(x)
29
+ x * 2
30
+ end
31
+ end
32
+ add = number.new.method(:add)
33
+ double = number.new.method(:double)
34
+ add_and_double = double * add
35
+
36
+ expect(add_and_double.call(1, 2)).to eq(6)
37
+ end
38
+
39
+ it 'passes blocks to g' do
40
+ number = Class.new do
41
+ def add(x, &blk)
42
+ x + blk.call
43
+ end
44
+
45
+ def double(x)
46
+ x * 2
47
+ end
48
+ end
49
+ add = number.new.method(:add)
50
+ double = number.new.method(:double)
51
+ add_and_double = double * add
52
+
53
+ expect(add_and_double.call(1) { 3 }).to eq(8)
54
+ end
55
+
56
+ it 'composes anything that responds to call' do
57
+ number = Class.new do
58
+ def triple(x)
59
+ x * 3
60
+ end
61
+ end
62
+ incrementer = Class.new do
63
+ def call(x)
64
+ x + 1
65
+ end
66
+ end
67
+
68
+ triple = number.new.method(:triple)
69
+ increment_and_triple = triple * incrementer.new
70
+
71
+ expect(increment_and_triple.call(1)).to eq(6)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,49 @@
1
+ require 'comp/proc'
2
+
3
+ RSpec.describe Proc do
4
+ describe '#*' do
5
+ it 'composes two Procs together' do
6
+ increment = proc { |x| x + 1 }
7
+ double = proc { |x| x * 2 }
8
+ increment_and_double = double * increment
9
+
10
+ expect(increment_and_double.call(1)).to eq(4)
11
+ end
12
+
13
+ it 'passes multiple arguments to g' do
14
+ add = proc { |x, y| x + y }
15
+ double = proc { |x| x * 2 }
16
+ add_and_double = double * add
17
+
18
+ expect(add_and_double.call(1, 2)).to eq(6)
19
+ end
20
+
21
+ it 'passes blocks to g' do
22
+ add = proc { |x, &blk| x + blk.call }
23
+ double = proc { |x| x * 2 }
24
+ add_and_double = double * add
25
+
26
+ expect(add_and_double.call(1) { 3 }).to eq(8)
27
+ end
28
+
29
+ it 'returns a lambda if f is a lambda' do
30
+ increment = proc { |x| x + 1 }
31
+ double = lambda { |x| x * 2 }
32
+
33
+ expect(double * increment).to be_lambda
34
+ end
35
+
36
+ it 'composes anything that responds to call' do
37
+ incrementer = Class.new do
38
+ def call(x)
39
+ x + 1
40
+ end
41
+ end
42
+
43
+ triple = lambda { |x| x * 3 }
44
+ increment_and_triple = triple * incrementer.new
45
+
46
+ expect(increment_and_triple.call(1)).to eq(6)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,19 @@
1
+ RSpec.configure do |config|
2
+ config.filter_run :focus
3
+ config.run_all_when_everything_filtered = true
4
+ config.example_status_persistence_file_path = 'spec/examples.txt'
5
+ config.disable_monkey_patching!
6
+ config.warnings = true
7
+ config.profile_examples = 10
8
+ config.order = :random
9
+ Kernel.srand config.seed
10
+ config.default_formatter = 'doc' if config.files_to_run.one?
11
+
12
+ config.expect_with :rspec do |expectations|
13
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
14
+ end
15
+
16
+ config.mock_with :rspec do |mocks|
17
+ mocks.verify_partial_doubles = true
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: comp
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Paul Mucur
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.3'
27
+ description: |2
28
+ A library to add functional composition between Procs and Methods in Ruby.
29
+ email: mudge@mudge.name
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - LICENSE
35
+ - README.md
36
+ - lib/comp.rb
37
+ - lib/comp/method.rb
38
+ - lib/comp/proc.rb
39
+ - spec/comp/method_spec.rb
40
+ - spec/comp/proc_spec.rb
41
+ - spec/spec_helper.rb
42
+ homepage: https://github.com/mudge/comp
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.4.5
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Functional composition with Procs and Methods in Ruby
66
+ test_files:
67
+ - spec/comp/method_spec.rb
68
+ - spec/comp/proc_spec.rb
69
+ - spec/spec_helper.rb