rns 0.0.1 → 0.0.2
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 +12 -10
- data/lib/rns/version.rb +2 -2
- data/lib/rns.rb +27 -16
- data/spec/rns/rns_spec.rb +60 -3
- metadata +2 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -13,22 +13,24 @@ functional programming in Ruby. It is inspired by
|
|
13
13
|
require 'rns'
|
14
14
|
|
15
15
|
module Arithmetic
|
16
|
-
|
17
|
-
|
16
|
+
class << self
|
17
|
+
def dec(n) n - 1 end
|
18
|
+
def inc(n) n + 1 end
|
19
|
+
end
|
18
20
|
end
|
19
21
|
|
20
22
|
module Statistics
|
21
|
-
def self.avg(arr); arr.reduce(:+) / arr.count
|
23
|
+
def self.avg(arr); arr.reduce(:+).to_f / arr.count end
|
22
24
|
end
|
23
25
|
|
24
|
-
class Main
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
class Main
|
27
|
+
include Rns
|
28
|
+
|
29
|
+
extend_specified Arithmetic => [:inc]
|
30
|
+
include_specified Statistics => [:avg]
|
29
31
|
|
30
32
|
def main
|
31
|
-
puts "1+1 is #{inc 1} and the average of [1,2,3] is #{avg [1,2,3]}"
|
33
|
+
puts "1+1 is #{self.class.inc 1} and the average of [1,2,3] is #{avg [1,2,3]}"
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
@@ -38,7 +40,7 @@ Main.new.main
|
|
38
40
|
## Importing Methods into Blocks
|
39
41
|
|
40
42
|
```ruby
|
41
|
-
Rns::using
|
43
|
+
Rns::using(Arithmetic => [:inc], Statistics => [:avg]) do
|
42
44
|
puts avg((1..10).to_a.map(&method(:inc)))
|
43
45
|
end
|
44
46
|
```
|
data/lib/rns/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.0.
|
1
|
+
module Rns
|
2
|
+
VERSION = "0.0.2"
|
3
3
|
end
|
data/lib/rns.rb
CHANGED
@@ -1,30 +1,41 @@
|
|
1
|
-
|
2
|
-
def self.
|
3
|
-
|
4
|
-
when Array then use_spec.each_slice(2).reduce([]){|xs,y| xs + [y]}
|
5
|
-
when Hash then use_spec.to_a
|
6
|
-
else
|
7
|
-
raise "Don't know how to make module/class:methods pairs out of #{use_spec.class}"
|
8
|
-
end
|
1
|
+
module Rns
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
9
4
|
end
|
10
5
|
|
11
|
-
def self.
|
12
|
-
|
13
|
-
|
6
|
+
def self.add_methods(to, use_spec)
|
7
|
+
use_spec.to_a.each do |from, method_names|
|
8
|
+
if (method_names.is_a? Hash)
|
9
|
+
add_methods(to, method_names.map do |k,v|
|
10
|
+
#TODO: is there a better way to construct modules?
|
11
|
+
{eval(from.to_s + "::" + k.to_s) => v}
|
12
|
+
end.reduce({}){|l,r| l.merge(r)})
|
13
|
+
else
|
14
14
|
method_names.each do |name|
|
15
|
-
|
16
|
-
|
15
|
+
if (name.is_a? Hash)
|
16
|
+
add_methods(to, {from => name})
|
17
|
+
else
|
18
|
+
to.send(:define_method, name) do |*args|
|
19
|
+
from.method(name).call(*args)
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
23
|
-
|
24
|
-
|
27
|
+
module ClassMethods
|
28
|
+
def include_specified(use_spec)
|
29
|
+
Rns::add_methods(self, use_spec)
|
30
|
+
end
|
31
|
+
|
32
|
+
def extend_specified(use_spec)
|
33
|
+
singleton_class = class << self; self; end
|
34
|
+
Rns::add_methods(singleton_class, use_spec)
|
35
|
+
end
|
25
36
|
end
|
26
37
|
|
27
38
|
def self.using(use_spec, &blk)
|
28
|
-
blk[Rns::
|
39
|
+
blk[Object.new.tap{|o| Rns::add_methods(o.class, use_spec)}]
|
29
40
|
end
|
30
41
|
end
|
data/spec/rns/rns_spec.rb
CHANGED
@@ -1,15 +1,72 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), *%w[.. spec_helper.rb])
|
2
2
|
require 'rns'
|
3
3
|
|
4
|
+
module Math
|
5
|
+
def self.identity(x); x end
|
6
|
+
|
7
|
+
module Arithmetic
|
8
|
+
class << self
|
9
|
+
def dec(n) n - one end
|
10
|
+
def inc(n) n + one end
|
11
|
+
private
|
12
|
+
def one() 1 end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Statistics
|
17
|
+
def self.avg(arr); arr.reduce(:+).to_f / arr.count end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Thing
|
22
|
+
include Rns
|
23
|
+
|
24
|
+
extend_specified Math::Arithmetic => [:inc]
|
25
|
+
include_specified Math::Statistics => [:avg]
|
26
|
+
|
27
|
+
def inced_one
|
28
|
+
self.class.inc 1
|
29
|
+
end
|
30
|
+
|
31
|
+
def average
|
32
|
+
avg [11, 42, 7]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
4
36
|
describe Rns do
|
5
37
|
context 'adding methods to classes' do
|
6
38
|
it "works" do
|
7
|
-
|
39
|
+
Thing.new.average.should == 20
|
40
|
+
end
|
41
|
+
|
42
|
+
it "works with private module methods" do
|
43
|
+
Thing.new.inced_one.should == 2
|
8
44
|
end
|
9
45
|
end
|
46
|
+
|
10
47
|
context 'adding methods to blocks' do
|
11
|
-
it "works" do
|
12
|
-
(
|
48
|
+
it "works with individual modules" do
|
49
|
+
Rns::using(Math::Arithmetic => [:inc],
|
50
|
+
Math::Statistics => [:avg]) do
|
51
|
+
avg((1..10).to_a.map(&method(:inc))).should == 6.5
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "works with nested modules" do
|
56
|
+
Rns::using(Math => {:Arithmetic => [:inc],
|
57
|
+
:Statistics => [:avg]}) do
|
58
|
+
avg((1..10).to_a.map(&method(:inc))).should == 6.5
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "works with mix of module declaration styles" do
|
63
|
+
Rns::using(Math::Arithmetic => [:inc],
|
64
|
+
Math => [:identity,
|
65
|
+
{:Statistics => [:avg]}]) do
|
66
|
+
identity(1).should == 1
|
67
|
+
inc(10).should == 11
|
68
|
+
avg((1..10).to_a.map(&method(:inc))).should == 6.5
|
69
|
+
end
|
13
70
|
end
|
14
71
|
end
|
15
72
|
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.2
|
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-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|