rns 0.0.2 → 0.0.3
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.
- data/Gemfile.lock +1 -1
- data/README.md +2 -4
- data/lib/rns/version.rb +1 -1
- data/lib/rns.rb +35 -29
- data/spec/rns/rns_spec.rb +86 -7
- metadata +2 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -24,10 +24,8 @@ module Statistics
|
|
24
24
|
end
|
25
25
|
|
26
26
|
class Main
|
27
|
-
|
28
|
-
|
29
|
-
extend_specified Arithmetic => [:inc]
|
30
|
-
include_specified Statistics => [:avg]
|
27
|
+
extend Rns.module_with(Arithmetic => [:inc])
|
28
|
+
include Rns.module_with(Statistics => [:avg])
|
31
29
|
|
32
30
|
def main
|
33
31
|
puts "1+1 is #{self.class.inc 1} and the average of [1,2,3] is #{avg [1,2,3]}"
|
data/lib/rns/version.rb
CHANGED
data/lib/rns.rb
CHANGED
@@ -1,41 +1,47 @@
|
|
1
1
|
module Rns
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
class << self
|
3
|
+
def constant_for(module_names)
|
4
|
+
(m, *more) = module_names.map{|n| n.split("::")}.flatten
|
5
|
+
more.reduce(Kernel.const_get(m)){|m, s| m.const_get(s)}
|
6
|
+
end
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
else
|
18
|
-
to.send(:define_method, name) do |*args|
|
19
|
-
from.method(name).call(*args)
|
20
|
-
end
|
21
|
-
end
|
8
|
+
def module_with(use_spec)
|
9
|
+
Module.new.tap {|m| add_methods(m, use_spec) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def process_spec_entry(entry)
|
13
|
+
(k,v) = entry
|
14
|
+
if (v.is_a? Array)
|
15
|
+
v.map{|x| process_spec_entry([k,x])}
|
16
|
+
elsif (v.is_a? Hash)
|
17
|
+
v.map do |x,y|
|
18
|
+
process_spec_entry([constant_for([k, x].map(&:to_s)), y])
|
22
19
|
end
|
20
|
+
else
|
21
|
+
[k,v]
|
23
22
|
end
|
24
23
|
end
|
25
|
-
end
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
def process_spec(use_spec)
|
26
|
+
use_spec.map(&method(:process_spec_entry)).
|
27
|
+
flatten.
|
28
|
+
each_slice(2).
|
29
|
+
to_a
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
32
|
+
def add_methods(to, use_spec)
|
33
|
+
process_spec(use_spec).each do |from, method|
|
34
|
+
to.send(:define_method, method) do |*args|
|
35
|
+
from.method(method).call(*args)
|
36
|
+
end
|
37
|
+
to.send(:private, method)
|
38
|
+
end
|
35
39
|
end
|
36
|
-
end
|
37
40
|
|
38
|
-
|
39
|
-
|
41
|
+
def using(use_spec, &blk)
|
42
|
+
klass = Class.new
|
43
|
+
add_methods(klass, use_spec)
|
44
|
+
klass.new.instance_eval(&blk)
|
45
|
+
end
|
40
46
|
end
|
41
47
|
end
|
data/spec/rns/rns_spec.rb
CHANGED
@@ -8,6 +8,7 @@ module Math
|
|
8
8
|
class << self
|
9
9
|
def dec(n) n - one end
|
10
10
|
def inc(n) n + one end
|
11
|
+
def add(x,y) x + y end
|
11
12
|
private
|
12
13
|
def one() 1 end
|
13
14
|
end
|
@@ -15,17 +16,40 @@ module Math
|
|
15
16
|
|
16
17
|
module Statistics
|
17
18
|
def self.avg(arr); arr.reduce(:+).to_f / arr.count end
|
19
|
+
module Foo
|
20
|
+
def self.blah; :quux end
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
21
|
-
|
22
|
-
|
25
|
+
module Util
|
26
|
+
class << self
|
27
|
+
def assoc!(h, k, v)
|
28
|
+
h.tap{|o| o[k] = v}
|
29
|
+
end
|
23
30
|
|
24
|
-
|
25
|
-
|
31
|
+
def merge_with(f, *hshs)
|
32
|
+
merge_entry = lambda do |h, (k,v)|
|
33
|
+
if (h.has_key?(k))
|
34
|
+
assoc!(h, k, f[h[k], v])
|
35
|
+
else
|
36
|
+
assoc!(h, k, v)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
merge2 = lambda do |h1,h2|
|
40
|
+
h2.to_a.reduce(h1, &merge_entry)
|
41
|
+
end
|
42
|
+
([{}] + hshs).reduce(&merge2)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
26
46
|
|
27
|
-
|
28
|
-
|
47
|
+
class Thing
|
48
|
+
extend Rns.module_with(Math::Arithmetic => [:inc])
|
49
|
+
include Rns.module_with(Math::Statistics => [:avg])
|
50
|
+
|
51
|
+
def self.inced_one
|
52
|
+
inc 1
|
29
53
|
end
|
30
54
|
|
31
55
|
def average
|
@@ -40,11 +64,33 @@ describe Rns do
|
|
40
64
|
end
|
41
65
|
|
42
66
|
it "works with private module methods" do
|
43
|
-
Thing.
|
67
|
+
Thing.inced_one.should == 2
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should add methods privately" do
|
71
|
+
lambda { Thing.new.avg [11, 42, 7] }.should raise_error(NoMethodError)
|
44
72
|
end
|
45
73
|
end
|
46
74
|
|
47
75
|
context 'adding methods to blocks' do
|
76
|
+
|
77
|
+
it 'computes' do
|
78
|
+
Rns::using(Util => [:merge_with],
|
79
|
+
Math::Arithmetic => [:inc, :add]) do
|
80
|
+
|
81
|
+
sum = lambda{|*xs| xs.reduce(:+)}
|
82
|
+
|
83
|
+
merge_with(sum, *(1..10).map{|n| {x: n}})[:x].should == 55
|
84
|
+
merge_with(sum,
|
85
|
+
{x: 10, y: 20},
|
86
|
+
{x: 3, z: 30}).should == {x: 13, y: 20, z: 30}
|
87
|
+
|
88
|
+
merge_with(lambda{|l,r| l.send(:+, r)},
|
89
|
+
{:x => [:something]},
|
90
|
+
{:x => [:else]}).should == {:x => [:something, :else]}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
48
94
|
it "works with individual modules" do
|
49
95
|
Rns::using(Math::Arithmetic => [:inc],
|
50
96
|
Math::Statistics => [:avg]) do
|
@@ -68,5 +114,38 @@ describe Rns do
|
|
68
114
|
avg((1..10).to_a.map(&method(:inc))).should == 6.5
|
69
115
|
end
|
70
116
|
end
|
117
|
+
|
118
|
+
it "does not modify Object" do
|
119
|
+
Rns::using(Math::Arithmetic => [:inc]) do
|
120
|
+
# do nothing
|
121
|
+
end
|
122
|
+
lambda { Object.new.inc 1 }.should raise_error(NoMethodError)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "does not modify Class" do
|
126
|
+
Rns::using(Math::Arithmetic => [:inc]) do
|
127
|
+
# do nothing
|
128
|
+
end
|
129
|
+
lambda { Class.new.inc 1 }.should raise_error(NoMethodError)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'processes specs correctly' do
|
133
|
+
Rns::using(Rns => [:process_spec]) do
|
134
|
+
process_spec({Math => [:inc, :dec]}).
|
135
|
+
should == [[Math, :inc], [Math, :dec]]
|
136
|
+
end
|
137
|
+
|
138
|
+
Rns::using(Rns => [:process_spec]) do
|
139
|
+
spec = {Math::Arithmetic => [:inc],
|
140
|
+
Math => [:identity,
|
141
|
+
{:Statistics => [:avg,
|
142
|
+
{:Foo => [:blah, :quux]}]}]}
|
143
|
+
process_spec(spec).should == [[Math::Arithmetic, :inc],
|
144
|
+
[Math, :identity],
|
145
|
+
[Math::Statistics, :avg],
|
146
|
+
[Math::Statistics::Foo, :blah],
|
147
|
+
[Math::Statistics::Foo, :quux]]
|
148
|
+
end
|
149
|
+
end
|
71
150
|
end
|
72
151
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|