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