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