rns 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rns (0.0.1)
4
+ rns (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
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
- def self.dec(n) n - 1; end
17
- def self.inc(n) n + 1; end
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; end
23
+ def self.avg(arr); arr.reduce(:+).to_f / arr.count end
22
24
  end
23
25
 
24
- class Main < Rns
25
- def use
26
- {Math => [:inc],
27
- Statistics => [:avg]}
28
- end
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 [Math, [:inc], Statistics, [:avg]] do
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
- class Rns
2
- VERSION = "0.0.1"
1
+ module Rns
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/rns.rb CHANGED
@@ -1,30 +1,41 @@
1
- class Rns
2
- def self.to_pairs(use_spec)
3
- case use_spec
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.populate(obj, use_spec)
12
- obj.tap do |o|
13
- to_pairs(use_spec).each do |pkg, method_names|
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
- o.class.send(:define_method, name) do |*args|
16
- pkg.method(name).call(*args)
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
- def initialize
24
- Rns::populate(self, use)
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::populate(Object.new, use_spec)]
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
- (1 + 1).should == 2
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
- (1 + 1).should == 2
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.1
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-05 00:00:00.000000000 Z
12
+ date: 2012-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec