iolite 0.0.1
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 +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
|