iolite 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +70 -0
- data/Rakefile +7 -0
- data/docs/iolite.md +278 -0
- data/example/array.rb +17 -0
- data/example/fizzbuzz.rb +15 -0
- data/example/hash.rb +14 -0
- data/example/minimal_implement.rb +42 -0
- data/example/simple.rb +46 -0
- data/example/to_lazy.rb +37 -0
- data/iolite.gemspec +24 -0
- data/lib/iolite.rb +14 -0
- data/lib/iolite/adaptor.rb +2 -0
- data/lib/iolite/adaptor/all.rb +22 -0
- data/lib/iolite/adaptor/apply.rb +10 -0
- data/lib/iolite/adaptor/bind.rb +9 -0
- data/lib/iolite/adaptor/callable.rb +7 -0
- data/lib/iolite/adaptor/define_send_original_methods.rb +12 -0
- data/lib/iolite/adaptor/method_missing.rb +10 -0
- data/lib/iolite/adaptor/operators.rb +26 -0
- data/lib/iolite/adaptor/send.rb +11 -0
- data/lib/iolite/adaptor/to_lazy.rb +11 -0
- data/lib/iolite/adaptor/to_proc.rb +10 -0
- data/lib/iolite/adaptored/array.rb +12 -0
- data/lib/iolite/adaptored/hash.rb +14 -0
- data/lib/iolite/adaptored/iolite_lazy_with_hash.rb +7 -0
- data/lib/iolite/adaptored/object_with_to_lazy.rb +5 -0
- data/lib/iolite/adaptored/proc.rb +5 -0
- data/lib/iolite/adaptored/string.rb +21 -0
- data/lib/iolite/functinal.rb +4 -0
- data/lib/iolite/functinal/bind.rb +12 -0
- data/lib/iolite/functinal/define_iolite_functinal_send_method.rb +9 -0
- data/lib/iolite/functinal/invoke.rb +11 -0
- data/lib/iolite/functinal/send.rb +13 -0
- data/lib/iolite/lazy.rb +40 -0
- data/lib/iolite/placeholders.rb +30 -0
- data/lib/iolite/refinements.rb +6 -0
- data/lib/iolite/refinements/array.rb +16 -0
- data/lib/iolite/refinements/hash.rb +18 -0
- data/lib/iolite/refinements/object_with_to_lazy.rb +9 -0
- data/lib/iolite/refinements/proc.rb +9 -0
- data/lib/iolite/refinements/string.rb +26 -0
- data/lib/iolite/statement.rb +3 -0
- data/lib/iolite/statement/if.rb +48 -0
- data/lib/iolite/statement/if_else.rb +11 -0
- data/lib/iolite/version.rb +3 -0
- data/spec/iolite_adaptored_spec.rb +101 -0
- data/spec/iolite_functinal_spec.rb +87 -0
- data/spec/iolite_lazy_spec.rb +92 -0
- data/spec/iolite_spec.rb +212 -0
- data/spec/spec_helper.rb +2 -0
- metadata +146 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
module Iolite module Functinal
|
2
|
+
def invoke func, *args
|
3
|
+
func.respond_to?(:iolite_functinal_invoke_call) ? func.iolite_functinal_invoke_call(*args) : func
|
4
|
+
end
|
5
|
+
module_function :invoke
|
6
|
+
|
7
|
+
def invoke_a funcs, *args
|
8
|
+
funcs.map{ |it| invoke(it, *args) }
|
9
|
+
end
|
10
|
+
module_function :invoke_a
|
11
|
+
end end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "iolite/functinal/invoke"
|
2
|
+
|
3
|
+
module Iolite module Functinal
|
4
|
+
def send func, method, *args_, &block
|
5
|
+
Lazy.new { |*args|
|
6
|
+
# block = invoke(block, *args) if block
|
7
|
+
invoke(func, *args).send(method, *invoke_a(args_, *args), &block)
|
8
|
+
# invoke(func, *args).send(method, *invoke_a(args_, *args), &block)
|
9
|
+
# func.call(*args).send(method, *invoke_a(args_, *args), &block)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
module_function :send
|
13
|
+
end end
|
data/lib/iolite/lazy.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "iolite/adaptor"
|
2
|
+
|
3
|
+
module Iolite
|
4
|
+
class Lazy < BasicObject
|
5
|
+
# include ::Iolite::Adaptor::All
|
6
|
+
include ::Iolite::Adaptor::Callable
|
7
|
+
include ::Iolite::Adaptor::Bind
|
8
|
+
include ::Iolite::Adaptor::Send
|
9
|
+
include ::Iolite::Adaptor::MethodMissing
|
10
|
+
include ::Iolite::Adaptor::ToProc
|
11
|
+
include ::Iolite::Adaptor::Apply
|
12
|
+
include ::Iolite::Adaptor::Operators
|
13
|
+
include ::Iolite::Adaptor::ToLazy
|
14
|
+
|
15
|
+
def initialize &block
|
16
|
+
@block = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def call *args
|
20
|
+
@block.call(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
# iolite_define_send_original_methods
|
24
|
+
end
|
25
|
+
|
26
|
+
def lazy &block
|
27
|
+
Iolite::Lazy.new &block
|
28
|
+
end
|
29
|
+
module_function :lazy
|
30
|
+
|
31
|
+
# def wrap value
|
32
|
+
# Iolite.lazy { |*args| value }
|
33
|
+
# end
|
34
|
+
# module_function :wrap
|
35
|
+
#
|
36
|
+
# def lazy_func func
|
37
|
+
# Iolite.lazy { |*args| func.call(*args) }
|
38
|
+
# end
|
39
|
+
# module_function :wrap
|
40
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "iolite/lazy"
|
2
|
+
|
3
|
+
module Iolite module Placeholders
|
4
|
+
def args
|
5
|
+
Lazy.new { |*args|
|
6
|
+
args
|
7
|
+
}
|
8
|
+
end
|
9
|
+
module_function :args
|
10
|
+
|
11
|
+
def argument index
|
12
|
+
Lazy.new { |*args|
|
13
|
+
args[index-1]
|
14
|
+
}
|
15
|
+
end
|
16
|
+
module_function :argument
|
17
|
+
|
18
|
+
def prepare n
|
19
|
+
1.upto(n).each { |i|
|
20
|
+
const_set("ARG#{i}", argument(i))
|
21
|
+
define_method("arg#{i}") do
|
22
|
+
Placeholders.const_get("ARG#{i}")
|
23
|
+
end
|
24
|
+
module_function "arg#{i}"
|
25
|
+
alias_method "_#{i}", "arg#{i}"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
module_function :prepare
|
29
|
+
prepare(10)
|
30
|
+
end end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "iolite/adaptor/all"
|
2
|
+
require "iolite/functinal/invoke"
|
3
|
+
|
4
|
+
module Iolite module Refinements
|
5
|
+
module Array
|
6
|
+
refine ::Array do
|
7
|
+
include Iolite::Adaptor::ToProc
|
8
|
+
include Iolite::Adaptor::Bind
|
9
|
+
include Iolite::Adaptor::Apply
|
10
|
+
include Iolite::Adaptor::Callable
|
11
|
+
def call *args
|
12
|
+
Iolite::Functinal.invoke_a(self, *args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "iolite/adaptor/all"
|
2
|
+
require "iolite/functinal/invoke"
|
3
|
+
|
4
|
+
module Iolite module Refinements
|
5
|
+
module Hash
|
6
|
+
refine ::Hash do
|
7
|
+
include Iolite::Adaptor::ToProc
|
8
|
+
include Iolite::Adaptor::Bind
|
9
|
+
include Iolite::Adaptor::Apply
|
10
|
+
include Iolite::Adaptor::Callable
|
11
|
+
def call *args
|
12
|
+
Hash[ self.map { |key, value|
|
13
|
+
Iolite::Functinal.invoke_a([key, value], *args)
|
14
|
+
} ]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "iolite/adaptor/all"
|
2
|
+
require "iolite/functinal/invoke"
|
3
|
+
|
4
|
+
module Iolite module Refinements
|
5
|
+
module String
|
6
|
+
refine ::String do
|
7
|
+
include Iolite::Adaptor::ToProc
|
8
|
+
include Iolite::Adaptor::Callable
|
9
|
+
def call *args
|
10
|
+
result = self.clone
|
11
|
+
args.each_with_index { |it, i|
|
12
|
+
result.gsub! Iolite::Placeholders.const_get("ARG#{i+1}").to_s, it.to_s
|
13
|
+
}
|
14
|
+
result
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_call_by_eval binding = nil
|
18
|
+
Iolite.lambda { |*args|
|
19
|
+
gsub(/#{'#{(.*?)}'}/) {
|
20
|
+
eval($1, binding).call(*args)
|
21
|
+
}
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "iolite/lazy"
|
2
|
+
require "iolite/functinal"
|
3
|
+
|
4
|
+
module Iolite module Statement
|
5
|
+
|
6
|
+
class IfThenElse
|
7
|
+
def initialize cond, then_
|
8
|
+
@cond = cond
|
9
|
+
@then_ = then_
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](*else_)
|
13
|
+
Iolite.lazy { |*args|
|
14
|
+
if Iolite::Functinal.invoke(@cond, *args)
|
15
|
+
Iolite::Functinal.invoke_a(@then_, *args).last
|
16
|
+
else
|
17
|
+
Iolite::Functinal.invoke_a(else_, *args).last
|
18
|
+
end
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class If
|
24
|
+
def initialize cond
|
25
|
+
@cond = cond
|
26
|
+
end
|
27
|
+
|
28
|
+
def [](*then_)
|
29
|
+
if_then = Iolite::Lazy.new { |*args|
|
30
|
+
if Iolite::Functinal.invoke(@cond, *args)
|
31
|
+
Iolite::Functinal.invoke_a(then_, *args).last
|
32
|
+
end
|
33
|
+
}
|
34
|
+
cond = @cond
|
35
|
+
(class << if_then; self; end).class_eval {
|
36
|
+
define_method(:else_) {
|
37
|
+
IfThenElse.new cond, then_
|
38
|
+
}
|
39
|
+
}
|
40
|
+
if_then
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def if_ cond
|
45
|
+
If.new cond
|
46
|
+
end
|
47
|
+
|
48
|
+
end end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
load 'spec_helper.rb'
|
2
|
+
require "iolite"
|
3
|
+
require "iolite/adaptored/array"
|
4
|
+
require "iolite/adaptored/hash"
|
5
|
+
require "iolite/adaptored/proc"
|
6
|
+
require "iolite/adaptored/string"
|
7
|
+
require "iolite/adaptored/object_with_to_lazy"
|
8
|
+
|
9
|
+
describe "Iolite Adaptored" do
|
10
|
+
include Iolite::Placeholders
|
11
|
+
|
12
|
+
describe "Array" do
|
13
|
+
it "call" do
|
14
|
+
expect([arg1, arg1, arg1].call(1)).to eq([1, 1, 1])
|
15
|
+
end
|
16
|
+
it "call with value" do
|
17
|
+
expect([arg1, 3, arg1].call(1)).to eq([1, 3, 1])
|
18
|
+
end
|
19
|
+
it "bind" do
|
20
|
+
expect([arg1, arg1, arg1].bind(arg2).call(1, 2)).to eq([2, 2, 2])
|
21
|
+
end
|
22
|
+
it "call invoke" do
|
23
|
+
expect(Iolite::Functinal.invoke([arg1, arg1, arg1], 1)).to eq([1, 1, 1])
|
24
|
+
end
|
25
|
+
it "nest" do
|
26
|
+
expect([arg1, [arg2, arg3]].call(1, 2, 3)).to eq([1, [2, 3]])
|
27
|
+
end
|
28
|
+
it "nest binding" do
|
29
|
+
expect([arg1, [arg1, arg2].bind(arg3, arg2)].call(1, 2, 3)).to eq([1, [3, 2]])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "Hash" do
|
34
|
+
it "call" do
|
35
|
+
expect({ arg1 => arg2 }.call(:name, :homu)).to eq({ name: :homu })
|
36
|
+
end
|
37
|
+
it "call key" do
|
38
|
+
expect({ arg1 => :mami }.call(:name, :homu)).to eq({ name: :mami })
|
39
|
+
end
|
40
|
+
it "call value" do
|
41
|
+
expect({ :mami => arg1 }.call(:name, :homu)).to eq({ mami: :name })
|
42
|
+
end
|
43
|
+
it "calls" do
|
44
|
+
expect({ arg1 => arg2, arg1 => arg3 }.call(:name, :homu, :mado)).to eq({ name: :homu, name: :mado })
|
45
|
+
end
|
46
|
+
it "bind" do
|
47
|
+
expect({ arg1 => arg3, arg2 => arg4 }.bind(arg1, arg1, arg2, arg3).call(:name, :homu, :mado)).to eq({ name: :homu, name: :mado })
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "Proc" do
|
52
|
+
describe "operator" do
|
53
|
+
it "proc" do
|
54
|
+
expect((proc { 10 } + 20).call()).to eq(30)
|
55
|
+
end
|
56
|
+
it "lambda" do
|
57
|
+
expect((lambda { 10 } + 20).call()).to eq(30)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
describe "bind" do
|
61
|
+
it "proc" do
|
62
|
+
expect(proc { |a, b| a + b }.bind(arg1, 2).call(1)).to eq(3)
|
63
|
+
end
|
64
|
+
it "lambda" do
|
65
|
+
expect(proc { |a, b| a - b }.bind(2, arg1).call(1)).to eq(1)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "String" do
|
71
|
+
include Iolite::Placeholders
|
72
|
+
it "call" do
|
73
|
+
expect("value:#{arg1}:#{arg2}".call(1, 2)).to eq("value:1:2")
|
74
|
+
end
|
75
|
+
it "#to_call_by_eval" do
|
76
|
+
expect('value:#{ Iolite::Placeholders.arg1 }:#{ Iolite::Placeholders.arg2 }'.to_call_by_eval.call(1, 2)).to eq("value:1:2")
|
77
|
+
end
|
78
|
+
it "#to_call_by_eval binding" do
|
79
|
+
var = 10
|
80
|
+
expect('value:#{ arg1 + arg2 * var }:#{ arg2 - arg1 }'.to_call_by_eval(binding).call(1, 2)).to eq("value:21:1")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "Object" do
|
85
|
+
describe "#to_lazy" do
|
86
|
+
it "lazy" do
|
87
|
+
expect(1.to_lazy.call()).to eq(1)
|
88
|
+
end
|
89
|
+
it "operator" do
|
90
|
+
expect((1.to_lazy + 2).call()).to eq(3)
|
91
|
+
end
|
92
|
+
it "operator with placeholder" do
|
93
|
+
expect((1.to_lazy + arg1).call(2)).to eq(3)
|
94
|
+
end
|
95
|
+
it "call method" do
|
96
|
+
expect(((1..10).to_lazy.first arg1).call(3)).to eq([1, 2, 3])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
load 'spec_helper.rb'
|
2
|
+
require "iolite/functinal"
|
3
|
+
|
4
|
+
|
5
|
+
describe "Iolite::Functinal" do
|
6
|
+
include Iolite::Functinal
|
7
|
+
class Callable
|
8
|
+
def iolite_functinal_invoke_call a, b
|
9
|
+
a + b
|
10
|
+
end
|
11
|
+
end
|
12
|
+
class Uncallable
|
13
|
+
def call x
|
14
|
+
x + x
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class First
|
19
|
+
def iolite_functinal_invoke_call *args
|
20
|
+
args[0]
|
21
|
+
end
|
22
|
+
def call *args
|
23
|
+
args[0]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
first = First.new
|
27
|
+
|
28
|
+
describe ".invoke" do
|
29
|
+
it "callable" do
|
30
|
+
expect(invoke(Callable.new, 1, 2)).to eq(3)
|
31
|
+
end
|
32
|
+
it "uncallable" do
|
33
|
+
expect(invoke(3, 1)).to eq(3)
|
34
|
+
end
|
35
|
+
it "uncallable call" do
|
36
|
+
expect(invoke(Uncallable.new, 1).class).to eq(Uncallable)
|
37
|
+
end
|
38
|
+
#it "uncallable proc" do
|
39
|
+
# expect(invoke(proc { |a, b| a + b }, 1, 2).class).to eq(Proc)
|
40
|
+
#end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe ".invoke_a" do
|
44
|
+
it "callable" do
|
45
|
+
expect(invoke_a([Callable.new, Callable.new], 1, 2)).to eq([3, 3])
|
46
|
+
end
|
47
|
+
it "uncallable" do
|
48
|
+
expect(invoke_a([1, 2], 1)).to eq([1, 2])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe ".send" do
|
53
|
+
it "send callable" do
|
54
|
+
expect(send(4, :+, Callable.new).call(1, 2)).to eq(7)
|
55
|
+
end
|
56
|
+
it "send callable" do
|
57
|
+
expect(send(Callable.new, :+, Callable.new).call(1, 2)).to eq(6)
|
58
|
+
end
|
59
|
+
it "send with block" do
|
60
|
+
expect(send(first, :select){ |it| it > 1 }.call([1, 2, 3])).to eq([2, 3])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe ".bind" do
|
65
|
+
# it "bind callable" do
|
66
|
+
# expect(bind(-> a, b { a + b }, 1, First.new).call(1, 2)).to eq(2)
|
67
|
+
# end
|
68
|
+
# it "bind method" do
|
69
|
+
# expect(bind(:+.to_proc, 1, First.new).call(2)).to eq(3)
|
70
|
+
# end
|
71
|
+
# it "bind next" do
|
72
|
+
# expect(bind(-> a, b { a + b }, bind(-> a, b { a + b }, First.new, First.new), First.new).call(3)).to eq(9)
|
73
|
+
# end
|
74
|
+
it "apply first" do
|
75
|
+
expect(bind(First.new, 1, 2).call(-> a, b { a + b })).to eq(3)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# describe ".apply" do
|
80
|
+
# it "call first" do
|
81
|
+
# expect(apply(-> a { -> b { a + b} }, 1).call(2)).to eq(3)
|
82
|
+
# end
|
83
|
+
# it "NoMethodError" do
|
84
|
+
# expect{ apply(-> a { 10 }, 1).call(2) }.to raise_error(NoMethodError)
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
end
|