comp 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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