iolite 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +70 -0
  8. data/Rakefile +7 -0
  9. data/docs/iolite.md +278 -0
  10. data/example/array.rb +17 -0
  11. data/example/fizzbuzz.rb +15 -0
  12. data/example/hash.rb +14 -0
  13. data/example/minimal_implement.rb +42 -0
  14. data/example/simple.rb +46 -0
  15. data/example/to_lazy.rb +37 -0
  16. data/iolite.gemspec +24 -0
  17. data/lib/iolite.rb +14 -0
  18. data/lib/iolite/adaptor.rb +2 -0
  19. data/lib/iolite/adaptor/all.rb +22 -0
  20. data/lib/iolite/adaptor/apply.rb +10 -0
  21. data/lib/iolite/adaptor/bind.rb +9 -0
  22. data/lib/iolite/adaptor/callable.rb +7 -0
  23. data/lib/iolite/adaptor/define_send_original_methods.rb +12 -0
  24. data/lib/iolite/adaptor/method_missing.rb +10 -0
  25. data/lib/iolite/adaptor/operators.rb +26 -0
  26. data/lib/iolite/adaptor/send.rb +11 -0
  27. data/lib/iolite/adaptor/to_lazy.rb +11 -0
  28. data/lib/iolite/adaptor/to_proc.rb +10 -0
  29. data/lib/iolite/adaptored/array.rb +12 -0
  30. data/lib/iolite/adaptored/hash.rb +14 -0
  31. data/lib/iolite/adaptored/iolite_lazy_with_hash.rb +7 -0
  32. data/lib/iolite/adaptored/object_with_to_lazy.rb +5 -0
  33. data/lib/iolite/adaptored/proc.rb +5 -0
  34. data/lib/iolite/adaptored/string.rb +21 -0
  35. data/lib/iolite/functinal.rb +4 -0
  36. data/lib/iolite/functinal/bind.rb +12 -0
  37. data/lib/iolite/functinal/define_iolite_functinal_send_method.rb +9 -0
  38. data/lib/iolite/functinal/invoke.rb +11 -0
  39. data/lib/iolite/functinal/send.rb +13 -0
  40. data/lib/iolite/lazy.rb +40 -0
  41. data/lib/iolite/placeholders.rb +30 -0
  42. data/lib/iolite/refinements.rb +6 -0
  43. data/lib/iolite/refinements/array.rb +16 -0
  44. data/lib/iolite/refinements/hash.rb +18 -0
  45. data/lib/iolite/refinements/object_with_to_lazy.rb +9 -0
  46. data/lib/iolite/refinements/proc.rb +9 -0
  47. data/lib/iolite/refinements/string.rb +26 -0
  48. data/lib/iolite/statement.rb +3 -0
  49. data/lib/iolite/statement/if.rb +48 -0
  50. data/lib/iolite/statement/if_else.rb +11 -0
  51. data/lib/iolite/version.rb +3 -0
  52. data/spec/iolite_adaptored_spec.rb +101 -0
  53. data/spec/iolite_functinal_spec.rb +87 -0
  54. data/spec/iolite_lazy_spec.rb +92 -0
  55. data/spec/iolite_spec.rb +212 -0
  56. data/spec/spec_helper.rb +2 -0
  57. metadata +146 -0
@@ -0,0 +1,9 @@
1
+ require "iolite/functinal/send"
2
+
3
+ class Module
4
+ def define_iolite_functinal_send_method send_name, define_name = send_name
5
+ define_method(define_name) { |*args|
6
+ Iolite::Functinal.send(self, send_name, *args)
7
+ }
8
+ end
9
+ end
@@ -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
@@ -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,6 @@
1
+ require "iolite/refinements/object_with_to_lazy"
2
+ # require "iolite/refinements/array"
3
+ # require "iolite/refinements/hash"
4
+ # require "iolite/refinements/proc"
5
+ # require "iolite/refinements/string"
6
+
@@ -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,9 @@
1
+ require "iolite/adaptor/to_lazy"
2
+
3
+ module Iolite module Refinements
4
+ module ObjectWithToLazy
5
+ refine Object do
6
+ include Iolite::Adaptor::ToLazy
7
+ end
8
+ end
9
+ end end
@@ -0,0 +1,9 @@
1
+ require "iolite/adaptor/all"
2
+
3
+ module Iolite module Refinements
4
+ module Proc
5
+ refine ::Proc do
6
+ include Iolite::Adaptor::All
7
+ end
8
+ end
9
+ 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,3 @@
1
+ require "iolite/statement/if"
2
+ require "iolite/statement/if_else"
3
+
@@ -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,11 @@
1
+ module Iolite module Statement
2
+ def if_else cond, then_, else_
3
+ Lazy.new { |*args|
4
+ if Functinal.invoke(cond, *args)
5
+ Functinal.invoke(then_, *args)
6
+ else
7
+ Functinal.invoke(else_, *args)
8
+ end
9
+ }
10
+ end
11
+ end end
@@ -0,0 +1,3 @@
1
+ module Iolite
2
+ VERSION = "0.0.1"
3
+ 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