with_refinements 0.4.0 → 0.5.0
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Gemfile.lock +1 -1
- data/examples/b.rb +33 -5
- data/lib/with_refinements.rb +56 -27
- data/lib/with_refinements/core_ext.rb +3 -0
- data/lib/with_refinements/version.rb +1 -1
- metadata +3 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 540b9343999aeee6303dc94c36486399f6852b5ec904114851c3b254de0805de
|
4
|
+
data.tar.gz: ba4682ae1ac92d3c2f1d3094fb75bbe39b9c02a74d88fe8d55b3383f049909a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a2689931a6e93e4355f6f6493c3002a7de1dacbb5a6cc4c940c10a72f445b73ba8fbde9ace4eeaacbf0526319864bbd0396b61dccce978b5884af20eb5021bc
|
7
|
+
data.tar.gz: de929a1c059c4488f9381cf7dd518beb3a0384f1e0e7cdb6303e85d9d1a615cf9bb86c682e61bf8a5451ee0bd2980cfa760d79187f070ff54539c67f13130b6a
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Gemfile.lock
CHANGED
data/examples/b.rb
CHANGED
@@ -2,6 +2,7 @@ require "benchmark_driver"
|
|
2
2
|
|
3
3
|
Benchmark.driver do |x|
|
4
4
|
x.prelude <<~RUBY
|
5
|
+
require "sin_refinements"
|
5
6
|
require "bundler/setup"
|
6
7
|
require "with_refinements"
|
7
8
|
|
@@ -14,18 +15,45 @@ Benchmark.driver do |x|
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
18
|
+
|
19
|
+
module Plain
|
20
|
+
refine(String) do
|
21
|
+
def world
|
22
|
+
-"world"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
using Plain
|
28
|
+
|
29
|
+
class String
|
30
|
+
def george
|
31
|
+
-"george"
|
32
|
+
end
|
33
|
+
end
|
17
34
|
RUBY
|
18
35
|
|
19
|
-
x.report 'plain', %{
|
20
|
-
|
21
|
-
|
36
|
+
x.report 'plain monkey patch', %{
|
37
|
+
"hello".george
|
38
|
+
}
|
39
|
+
|
40
|
+
x.report 'plain refinements', %{
|
41
|
+
"hello".world
|
22
42
|
}
|
23
43
|
|
24
44
|
x.report 'with_refinements', %{
|
25
45
|
with_refinements(M) { "hello".goodbye }
|
26
46
|
}
|
27
47
|
|
28
|
-
x.report '
|
29
|
-
|
48
|
+
x.report 'with_refinements_light', %{
|
49
|
+
with_refinements_light(M) { "hello".goodbye }
|
50
|
+
}
|
51
|
+
|
52
|
+
x.report 'SinRefinements.refining', %{
|
53
|
+
SinRefinements.refining(M) { "hello".goodbye }
|
54
|
+
}
|
55
|
+
|
56
|
+
x.report 'SinRefinements.light_refining', %{
|
57
|
+
SinRefinements.light_refining(M) { "hello".goodbye }
|
30
58
|
}
|
31
59
|
end
|
data/lib/with_refinements.rb
CHANGED
@@ -1,15 +1,56 @@
|
|
1
1
|
require "with_refinements/version"
|
2
2
|
|
3
3
|
module WithRefinements
|
4
|
+
@context_cache = {}
|
5
|
+
@refined_proc_cache = Hash.new {|h,k| h[k] = {} }
|
6
|
+
@refined_proc_light_cache = Hash.new {|h,k| h[k] = {} }
|
7
|
+
|
4
8
|
class << self
|
5
|
-
def
|
6
|
-
|
9
|
+
def context(refinements)
|
10
|
+
@context_cache[refinements] ||= clean_binding.tap do |b|
|
11
|
+
b.local_variable_set(:__refinements__, refinements)
|
12
|
+
b.eval('__refinements__.each {|r| using r }')
|
13
|
+
end
|
7
14
|
end
|
8
15
|
|
9
|
-
def
|
16
|
+
def refined_proc(c, block)
|
17
|
+
@refined_proc_cache[c][block.source_location] ||= (
|
18
|
+
lvars = block.binding.local_variables
|
19
|
+
c.eval(<<~RUBY)
|
20
|
+
proc do |__binding__|
|
21
|
+
proc { |#{lvars.join(",")}|
|
22
|
+
ret = __binding__.receiver.instance_exec #{code_from_block(block)}
|
23
|
+
#{lvars.map {|v| "__binding__.local_variable_set(:#{v}, #{v})" }.join("\n")}
|
24
|
+
ret
|
25
|
+
}.call(*__binding__.local_variables.map {|v| __binding__.local_variable_get(v) })
|
26
|
+
end
|
27
|
+
RUBY
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def refined_proc_light(c, block)
|
32
|
+
@refined_proc_light_cache[c][block.source_location] ||= (
|
33
|
+
c.eval(<<~RUBY)
|
34
|
+
proc { |__receiver__, __args__| __receiver__.instance_exec(*__args__) #{code_from_block(block)} }
|
35
|
+
RUBY
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def block_source_location(block)
|
10
42
|
iseq = RubyVM::InstructionSequence.of(block).to_a
|
11
43
|
loc = iseq[4].yield_self {|h| h[:code_range] || h[:code_location] }
|
12
44
|
path = iseq[7]
|
45
|
+
return path, loc
|
46
|
+
end
|
47
|
+
|
48
|
+
def clean_binding
|
49
|
+
TOPLEVEL_BINDING.eval('Module.new { break binding }')
|
50
|
+
end
|
51
|
+
|
52
|
+
def code_from_block(block)
|
53
|
+
path, loc = block_source_location(block)
|
13
54
|
File.readlines(path)[loc[0]-1..loc[2]-1].tap {|ls|
|
14
55
|
if loc[0] == loc[2]
|
15
56
|
ls[0] = ls[0][loc[1]...loc[3]]
|
@@ -25,31 +66,19 @@ module WithRefinements
|
|
25
66
|
end
|
26
67
|
end
|
27
68
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
b.eval('__modules__.each {|m| using m }')
|
34
|
-
|
35
|
-
# setup block eval context
|
36
|
-
bb = block.binding
|
37
|
-
b.local_variable_set(:__self__, bb.receiver)
|
38
|
-
|
39
|
-
# copy local_variables
|
40
|
-
if local_variables
|
41
|
-
bb.local_variables.each {|n| b.local_variable_set(n, bb.local_variable_get(n)) }
|
42
|
-
end
|
69
|
+
def with_refinements(*refinements, &block)
|
70
|
+
c = WithRefinements.context(refinements)
|
71
|
+
p = WithRefinements.refined_proc(c, block)
|
72
|
+
p.call(block.binding)
|
73
|
+
end
|
43
74
|
|
44
|
-
|
45
|
-
|
75
|
+
def with_refinements_light(*refinements, args: [], &block)
|
76
|
+
c = WithRefinements.context(refinements)
|
77
|
+
p = WithRefinements.refined_proc_light(c, block)
|
78
|
+
p.call(block.binding.receiver, args)
|
79
|
+
end
|
46
80
|
|
47
|
-
|
48
|
-
if local_variables
|
49
|
-
bb.local_variables.each {|n| bb.local_variable_set(n, b.local_variable_get(n)) }
|
50
|
-
end
|
81
|
+
module_function :with_refinements, :with_refinements_light
|
51
82
|
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|
83
|
+
refine(Object) { include WithRefinements }
|
55
84
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: with_refinements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seiei Miyagi
|
@@ -34,7 +34,7 @@ cert_chain:
|
|
34
34
|
OKwDKKYe2ogJ/XrOjTltlugSNvq/NgD53wc4TA0F5KofdIZSJELTCUyyZMPztwI4
|
35
35
|
OawPtyIyOegL6pM8fc7IfzLzjkdO3Bis1qFZcg==
|
36
36
|
-----END CERTIFICATE-----
|
37
|
-
date: 2018-08-
|
37
|
+
date: 2018-08-04 00:00:00.000000000 Z
|
38
38
|
dependencies:
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: bundler
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- examples/b.rb
|
112
112
|
- examples/greeting.rb
|
113
113
|
- lib/with_refinements.rb
|
114
|
+
- lib/with_refinements/core_ext.rb
|
114
115
|
- lib/with_refinements/version.rb
|
115
116
|
- with_refinements.gemspec
|
116
117
|
homepage: https://github.com/hanachin/with_refinements
|
metadata.gz.sig
CHANGED
Binary file
|