trick 0.0.2 → 0.0.3
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 +4 -4
- data/README.md +46 -14
- data/lib/trick/function.rb +25 -0
- data/lib/trick/value.rb +29 -0
- data/lib/trick/version.rb +1 -1
- data/spec/function_spec.rb +47 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/entities.rb +75 -0
- data/spec/value_spec.rb +58 -0
- metadata +10 -8
- data/lib/trick/factory.rb +0 -11
- data/lib/trick/proclike.rb +0 -11
- data/spec/factory_spec.rb +0 -42
- data/spec/proclike_spec.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7356be74713ef841a26e2eea69ac8acb185ea1a9
|
4
|
+
data.tar.gz: a820f66c59f7acdd02c7cafc2d2920bac5529243
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57509be46dc4f257ce85cb95fdc76fb732297fbad3b820cbfc277616287a68cfc9ea44b12f672c6d952496abd83d9ace21bfaa372549c5350d655dc56b5d6c69
|
7
|
+
data.tar.gz: 2a2c9b580ae20850080cbd6500fa03b6ff3b66c6bc6fdeec79ea15027a533d0fd048b2cc8efa3b264e4da9bac547383abc8c0a4379ecb49177f04946d3d5f6d3
|
data/README.md
CHANGED
@@ -20,33 +20,65 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
### Turn something into a proc
|
23
|
+
### 1. Turn something into a proc
|
24
|
+
|
24
25
|
```ruby
|
25
|
-
|
26
|
-
extend Trick::
|
26
|
+
Point = Struct.new :coords do
|
27
|
+
extend Trick::Value
|
27
28
|
|
28
|
-
def
|
29
|
-
|
29
|
+
def radius
|
30
|
+
Math.sqrt(coords[0]**2 + coords[1]**2)
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
33
|
-
|
34
|
-
[
|
34
|
+
# create a list with proclike factory
|
35
|
+
points = [[3, 4], [8, 6]].map(&Point)
|
36
|
+
points.map(&:radius) # => [5, 10]
|
35
37
|
|
36
|
-
|
37
|
-
extend Trick::
|
38
|
+
module NormalizedDistance
|
39
|
+
extend Trick::Function
|
38
40
|
|
39
|
-
|
41
|
+
# main function method
|
42
|
+
def call(divisor, point)
|
43
|
+
point.radius / divisor * (inc_order? ? 10 : 100)
|
44
|
+
end
|
40
45
|
|
41
|
-
|
42
|
-
|
46
|
+
# use private methods in your function
|
47
|
+
private def inc_order?
|
48
|
+
point.coords[1] > point.coords[0]
|
43
49
|
end
|
44
50
|
end
|
45
51
|
|
46
|
-
|
47
|
-
[5
|
52
|
+
# map points with curried function
|
53
|
+
NormalizedDistance[5] # => curried proc
|
54
|
+
points.map(&NormalizedDistance[5]) # => [10, 200]
|
48
55
|
```
|
49
56
|
|
57
|
+
#### 1.1 Currying
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# class currying:
|
61
|
+
class Sum
|
62
|
+
extend Trick::Value
|
63
|
+
|
64
|
+
attr_reader :sum
|
65
|
+
|
66
|
+
def initialize(a, b)
|
67
|
+
@sum = a + b
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
Sum[41] # => curried proc
|
72
|
+
Sum[1, 2].sum # => 3
|
73
|
+
|
74
|
+
# struct currying:
|
75
|
+
A = Struct.new :x, :y do
|
76
|
+
extend Trick::Value
|
77
|
+
end
|
78
|
+
|
79
|
+
A[1] # => curried proc
|
80
|
+
A[1, 2] # => struct A[1, 2]
|
81
|
+
```
|
50
82
|
|
51
83
|
|
52
84
|
## Contributing
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Trick
|
2
|
+
module Function
|
3
|
+
# TODO:
|
4
|
+
# `module_function` does not work here, would we use it instead of
|
5
|
+
# `extend`?
|
6
|
+
def self.extended(base)
|
7
|
+
base.extend base
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_proc
|
11
|
+
method(:call).to_proc
|
12
|
+
end
|
13
|
+
|
14
|
+
def curry(arity = nil)
|
15
|
+
to_proc.curry(arity)
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](*args, &block)
|
19
|
+
curry[*args, &block]
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(*)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/trick/value.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "trick/function"
|
2
|
+
|
3
|
+
module Trick
|
4
|
+
module Value
|
5
|
+
def self.extended(base)
|
6
|
+
if base.superclass == Struct
|
7
|
+
base.define_singleton_method(:[]) do |*args, &block|
|
8
|
+
curry(base.members.count)[*args, &block]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_proc
|
14
|
+
method(:new).to_proc
|
15
|
+
end
|
16
|
+
|
17
|
+
def curry(arity = nil)
|
18
|
+
to_proc.curry(arity || instance_method(:initialize).arity)
|
19
|
+
end
|
20
|
+
|
21
|
+
def [](*args, &block)
|
22
|
+
curry[*args, &block]
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(*args)
|
26
|
+
new(*args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/trick/version.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
require "trick/function"
|
2
|
+
|
3
|
+
RSpec.describe Trick::Function do
|
4
|
+
def args
|
5
|
+
[:a, "b", 1, nil, [], {}]
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "::to_proc" do
|
9
|
+
it "returns a Proc" do
|
10
|
+
expect(ABC.to_proc).to be_a Proc
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns callable with arguments" do
|
14
|
+
expect(ABC.to_proc.call(*args)).to eq ABC.call(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "applies as a block" do
|
18
|
+
expect(
|
19
|
+
["A", "B", "C"].map(&Letter)
|
20
|
+
).to eq ["Letter A", "Letter B", "Letter C"]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "applies curried proc as a block" do
|
24
|
+
expect(points.map(&NormalizedDistance[5])).to eq [10, 200]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "::curry" do
|
29
|
+
it "returns a curried Proc" do
|
30
|
+
expect(Clean["mop"]).to be_a Proc
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns a result of curried Proc's applying" do
|
34
|
+
expect(Clean["mop"].("hall")).to eq "Clean hall with mop"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "::call" do
|
39
|
+
it { expect(ABC).to respond_to(:call) }
|
40
|
+
|
41
|
+
it "accepts any arguments" do
|
42
|
+
expect { ABC.call(*args) }.not_to raise_error
|
43
|
+
end
|
44
|
+
|
45
|
+
it { expect(ABC.call).to eq nil }
|
46
|
+
end
|
47
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
Dir["./spec/support/**/*.rb"].each { |f| require f }
|
2
|
+
|
1
3
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
4
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
5
|
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require "trick/function"
|
2
|
+
require "trick/value"
|
3
|
+
|
4
|
+
module ABC
|
5
|
+
extend Trick::Function
|
6
|
+
end
|
7
|
+
|
8
|
+
module Letter
|
9
|
+
extend Trick::Function
|
10
|
+
|
11
|
+
def call(x)
|
12
|
+
"Letter #{x}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Clean
|
17
|
+
extend Trick::Function
|
18
|
+
|
19
|
+
def call(tool, room)
|
20
|
+
"Clean #{room} with #{tool}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
A = Struct.new :x, :y do
|
26
|
+
extend Trick::Value
|
27
|
+
end
|
28
|
+
|
29
|
+
class RoundedNum
|
30
|
+
extend Trick::Value
|
31
|
+
|
32
|
+
attr_reader :value
|
33
|
+
|
34
|
+
def initialize(number)
|
35
|
+
@value = number.round
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Sum
|
40
|
+
extend Trick::Value
|
41
|
+
|
42
|
+
attr_reader :sum
|
43
|
+
|
44
|
+
def initialize(a, b)
|
45
|
+
@sum = a + b
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# README
|
51
|
+
Point = Struct.new :coords do
|
52
|
+
extend Trick::Value
|
53
|
+
|
54
|
+
def radius
|
55
|
+
Math.sqrt(coords[0]**2 + coords[1]**2)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def points
|
60
|
+
@points ||= [[3, 4], [8, 6]].map(&Point)
|
61
|
+
end
|
62
|
+
|
63
|
+
module NormalizedDistance
|
64
|
+
extend Trick::Function
|
65
|
+
|
66
|
+
# main function method
|
67
|
+
def call(divisor, point)
|
68
|
+
point.radius / divisor * (inc_order?(point) ? 10 : 100)
|
69
|
+
end
|
70
|
+
|
71
|
+
# use private methods in your function
|
72
|
+
private def inc_order?(point)
|
73
|
+
point.coords[1] > point.coords[0]
|
74
|
+
end
|
75
|
+
end
|
data/spec/value_spec.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require "trick/value"
|
2
|
+
|
3
|
+
RSpec.describe Trick::Value do
|
4
|
+
describe "::to_proc" do
|
5
|
+
it "acts as a constructor of a class" do
|
6
|
+
expect(
|
7
|
+
[5.75, 0.99].map(&RoundedNum).map(&:value)
|
8
|
+
).to eq [6, 1]
|
9
|
+
end
|
10
|
+
|
11
|
+
it "constructs instances", :readme do
|
12
|
+
expect(points).to eq [Point.new([3, 4]), Point.new([8, 6])]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "constructs instances with ability to pass messages to them", :readme do
|
16
|
+
expect(points.map(&:radius)).to eq [5, 10]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "::curry" do
|
21
|
+
context "Struct" do
|
22
|
+
it "returns a struct class", :readme do
|
23
|
+
expect(A[1]).to be_a Proc
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns a result of instantiating a struct" do
|
27
|
+
expect(A[1, 2]).to eq A[1, 2]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "class", :readme do
|
32
|
+
it "returns a curried Proc" do
|
33
|
+
expect(Sum[41]).to be_a Proc
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns a result of curried Proc's applying" do
|
37
|
+
expect(Sum[1, 2].sum).to eq 3
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "::call" do
|
43
|
+
it "returns new instance of a class" do
|
44
|
+
expect(A.(10, 17)).to be_a A
|
45
|
+
end
|
46
|
+
|
47
|
+
it "creates an instance with passed values" do
|
48
|
+
a = A.(1, 2)
|
49
|
+
|
50
|
+
expect(a.x).to eq 1
|
51
|
+
expect(a.y).to eq 2
|
52
|
+
end
|
53
|
+
|
54
|
+
it "creates an instance with passed value" do
|
55
|
+
expect(RoundedNum.(3.333).value).to eq 3
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitry Novikov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,12 +66,13 @@ files:
|
|
66
66
|
- README.md
|
67
67
|
- Rakefile
|
68
68
|
- lib/trick.rb
|
69
|
-
- lib/trick/
|
70
|
-
- lib/trick/
|
69
|
+
- lib/trick/function.rb
|
70
|
+
- lib/trick/value.rb
|
71
71
|
- lib/trick/version.rb
|
72
|
-
- spec/
|
73
|
-
- spec/proclike_spec.rb
|
72
|
+
- spec/function_spec.rb
|
74
73
|
- spec/spec_helper.rb
|
74
|
+
- spec/support/entities.rb
|
75
|
+
- spec/value_spec.rb
|
75
76
|
- trick.gemspec
|
76
77
|
homepage: ''
|
77
78
|
licenses:
|
@@ -98,6 +99,7 @@ signing_key:
|
|
98
99
|
specification_version: 4
|
99
100
|
summary: Ruby syntax enhancements.
|
100
101
|
test_files:
|
101
|
-
- spec/
|
102
|
-
- spec/proclike_spec.rb
|
102
|
+
- spec/function_spec.rb
|
103
103
|
- spec/spec_helper.rb
|
104
|
+
- spec/support/entities.rb
|
105
|
+
- spec/value_spec.rb
|
data/lib/trick/factory.rb
DELETED
data/lib/trick/proclike.rb
DELETED
data/spec/factory_spec.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
require "trick/factory"
|
2
|
-
|
3
|
-
RSpec.describe Trick::Factory do
|
4
|
-
A = Struct.new :x, :y do
|
5
|
-
extend Trick::Factory
|
6
|
-
end
|
7
|
-
|
8
|
-
class RoundedNum
|
9
|
-
extend Trick::Factory
|
10
|
-
|
11
|
-
attr_reader :value
|
12
|
-
|
13
|
-
def initialize(number)
|
14
|
-
@value = number.round
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe "::to_proc" do
|
19
|
-
it "acts as a constructor of a class", :readme do
|
20
|
-
expect(
|
21
|
-
[5.75, 0.99].map(&RoundedNum).map(&:value)
|
22
|
-
).to eq [6, 1]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "::call" do
|
27
|
-
it "returns new instance of a class" do
|
28
|
-
expect(A.(10, 17)).to be_a A
|
29
|
-
end
|
30
|
-
|
31
|
-
it "creates an instance with passed values" do
|
32
|
-
a = A.(1, 2)
|
33
|
-
|
34
|
-
expect(a.x).to eq 1
|
35
|
-
expect(a.y).to eq 2
|
36
|
-
end
|
37
|
-
|
38
|
-
it "creates an instance with passed value", :readme do
|
39
|
-
expect(RoundedNum.(3.333).value).to eq 3
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/spec/proclike_spec.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
require "trick/proclike"
|
2
|
-
|
3
|
-
RSpec.describe Trick::Proclike do
|
4
|
-
module ABC
|
5
|
-
extend Trick::Proclike
|
6
|
-
end
|
7
|
-
|
8
|
-
module Letter
|
9
|
-
extend Trick::Proclike
|
10
|
-
|
11
|
-
def self.call(x)
|
12
|
-
"Letter #{x}"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def args
|
17
|
-
[:a, "b", 1, nil, [], {}]
|
18
|
-
end
|
19
|
-
|
20
|
-
subject { ABC }
|
21
|
-
|
22
|
-
describe "::to_proc" do
|
23
|
-
it "returns a Proc" do
|
24
|
-
expect(ABC.to_proc).to be_a Proc
|
25
|
-
end
|
26
|
-
|
27
|
-
it "returns callable with arguments" do
|
28
|
-
expect(ABC.to_proc.call(*args)).to eq ABC.call(*args)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "applies as a block", :readme do
|
32
|
-
expect(
|
33
|
-
["B", "C"].map(&Letter)
|
34
|
-
).to eq ["Letter B", "Letter C"]
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe "::call" do
|
39
|
-
it { is_expected.to respond_to(:call) }
|
40
|
-
|
41
|
-
it "accepts any arguments" do
|
42
|
-
expect { ABC.call(*args) }.not_to raise_error
|
43
|
-
end
|
44
|
-
|
45
|
-
it { expect(ABC.call).to eq ABC }
|
46
|
-
end
|
47
|
-
end
|