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.
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