functions 0.0.12 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- N2Q2YWQzNDg3ZDc2MTRjMGZlNjhhOGUwYTM2MmYzMmEwZjBjN2JiMA==
5
- data.tar.gz: !binary |-
6
- ZmYzMDBlZjM2NTZhNmE4MDBjOWRlYjMxNmY3MWViMjFlMjc0OTE0MA==
2
+ SHA1:
3
+ metadata.gz: c6dc48ecaa2924694dc2ca346aa3b085b6d61d0d
4
+ data.tar.gz: cc1476f81c7bc6857ffb5bc3ef39e1a64c2d0cbf
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZGJkYWJmOTIxNzE2MGVmZDllMjU5ZDY3ZDZlYjc0YWM2NDI2YThkOTUzZGMw
10
- ZDg1NjZiN2Q1MjI0NmY2OTNhMmI2Zjc1ODI2NWFhYmQzMjZjM2VjMTQxMzZk
11
- M2VjNDFjNTYwZDlmYTBkNzVjZTU5MDhhN2ExZWUzZTcxN2YzNjY=
12
- data.tar.gz: !binary |-
13
- NjEwOGRmMzc5ODRlODU3ZGE2ZGQ5NGRiMDE1ZWFhMGI2MTkwOGI5MDdjZTdl
14
- NDhmOGJkNDJhOGU3NzRlZDA2ZDFjZGU4ZjFiN2M0OTdhZTA3NjBhZmUwMTUw
15
- NzNlZDM1YzMzNDMwMGQxZDY5YzRkOTg1NTVjNTZkNjUxMWZiYmI=
6
+ metadata.gz: 396ed57977054e246c594530cd25b08c4cabb379464189ef06c6bfb9939045a282512526111e3a901cd7bb3f99af889d282498923e266fe19e1fb1ed08d1926f
7
+ data.tar.gz: 10a22bc2fdd3115fdabc7bed2312d1951d5bddc01b69d110f199bfccba2c31baab3bdc3e2748e2f958dc0fd2ec379a20eade9f5e33a3834e403693f3d73458cd
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Functional
2
2
 
3
- This library facilitates writing code in a more functional style inside Ruby.
4
- How this is fun.
3
+ This library facilitates writing code in a more functional style inside Ruby.
5
4
 
6
5
  ## Installation
7
6
 
@@ -19,12 +18,6 @@ Or install it yourself as:
19
18
 
20
19
  ## Usage
21
20
 
22
- The library provides two different styles.
23
- One style builds on Lambda's and another style uses meta-programming.
24
- The lambda style is a bit more pure but is currently just a bit slower in performance.
25
-
26
- ### Lambda Style
27
-
28
21
  The lambda style allows you to write functions like this
29
22
 
30
23
  require 'functions'
@@ -51,32 +44,6 @@ The lambda style allows you to write functions like this
51
44
 
52
45
  end
53
46
 
54
- ### Meta Style
55
-
56
- The meta style allows you to write functions like this
57
-
58
- require 'functions'
59
-
60
- module PreludeMetaUsage
61
-
62
- include Functions::PreludeMeta
63
-
64
- def power(x, p) x ** p end
65
-
66
- def square(x) power(x, 2) end
67
-
68
- define :squares, as: { map: :square }
69
-
70
- define :evens, as: { filter: :even? }
71
-
72
- define :sum_of_squares_tris, as: { compose: [:sum, :squares] }
73
-
74
- define :average, as: { :after => [ :sum_length, :divide ] }
75
-
76
- define :sum, as: { foldl: [:add, 0]}
77
-
78
- end
79
-
80
47
  ## License
81
48
 
82
49
  This code is currently copyrighted under the AGPL license.
@@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
11
11
  gem.description = %q{functional programming in ruby}
12
12
  gem.summary = %q{functional programming in ruby}
13
13
  gem.homepage = "https://github.com/koenhandekyn/functions"
14
-
14
+ gem.license = 'MIT'
15
15
  gem.files = `git ls-files`.split($/)
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
@@ -0,0 +1,2 @@
1
+ require_relative 'prelude_enumerable/enumerable'
2
+ require_relative 'prelude_enumerable/hash'
@@ -0,0 +1,47 @@
1
+ module Enumerable
2
+
3
+ def zip_map *lists, &b
4
+ self.zip(*lists).map(&b)
5
+ end
6
+
7
+ def unzip
8
+ self.transpose
9
+ end
10
+
11
+ # splits a list xs in n peices
12
+ def split_in(n)
13
+ (split = self.each_slice((self.length+1)/n).to_a).concat [[]] * (n-split.length)
14
+ end
15
+
16
+ def split_in_half
17
+ split_in(2)
18
+ end
19
+
20
+ def counted_set
21
+ self.inject( Hash.new(0) ) { |h,e| h[e] += 1; h }
22
+ end
23
+
24
+ def grouped_by &f
25
+ self.group_by(&f).values
26
+ end
27
+
28
+ def interleave ys
29
+ self.zip(ys).flatten.compact
30
+ end
31
+
32
+ # merges two ordered lists by a function f that compares the values
33
+ # if no function is given the values are compared by the "<" operator
34
+ def merge ys, &f
35
+
36
+ return self.dup if ys.empty?
37
+ return ys.dup if self.empty?
38
+
39
+ x, *xt = self
40
+ y, *yt = ys
41
+
42
+ return ys.merge(xt, &f) >> x if ( f.nil? ? x < y : f.(x,y) )
43
+ return self.merge(yt, &f) >> y
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,15 @@
1
+ class Hash
2
+
3
+ def zip_hash_left(bs)
4
+ self.each_with_object({}) { |(k, a), h| h[k] = [a, bs[k]]; h }
5
+ end
6
+
7
+ def zip_hash_inner(bs)
8
+ self.each_with_object({}) { |(k, a), h| b = bs[k]; h[k] = [a, b] if b; h }
9
+ end
10
+
11
+ def map_hash
12
+ Hash[self.map{|k, v| [k, yield(v)] }]
13
+ end
14
+
15
+ end
@@ -14,7 +14,7 @@ module Functions
14
14
  # splits a list in half
15
15
  Split_In_Half = Split_In.curry.(2)
16
16
 
17
- # merges two lists by a function f that compares the values
17
+ # merges two ordered lists by a function f that compares the values
18
18
  # if no function is given the values are compared by the "<" operator
19
19
  Merge_By = ->(f, xs, ys) do
20
20
 
@@ -105,6 +105,7 @@ module Functions
105
105
 
106
106
  Values = Send.(:values)
107
107
 
108
+ # TODO investigate semantics
108
109
  Partition = ->(f) { Group.(f) > Values }
109
110
 
110
111
  FromTo = ->(from) { ->(to) { Range.new(from, to) } }
@@ -14,6 +14,8 @@ module Functions
14
14
 
15
15
  Average = Parallel.(Sum,Length) > Divide
16
16
 
17
+ Power = ->(p,x) { x**p }.curry
18
+
17
19
  IsDivisor = ->(a, c) { a % c == 0 }
18
20
 
19
21
  Divisors = ->(a) { Filter.(IsDivisor.partial(a), FromOneTo.(a)) }
@@ -5,17 +5,19 @@ module Functions
5
5
  Merge_Sort_By = ->(f, xs) do
6
6
 
7
7
  return xs if xs.length <= 1 # stopcondition
8
-
8
+
9
9
  left, right = Split_In_Half.(xs)
10
10
  Merge_By.(f, Merge_Sort_By.(f, left), Merge_Sort_By.(f, right))
11
-
12
11
  end
13
12
 
14
13
  Merge_Sort = Merge_Sort_By.partial(nil)
14
+ # = Merge_Sort_By.partial(Identity)
15
15
 
16
16
  Quick_Sort_By = ->(f, list) do
17
+
17
18
  return [] if list.size == 0
18
19
  return list if list.size == 1
20
+
19
21
  pivot, *xs = *list
20
22
  smaller_than = f.nil? ? ->(y) { y < pivot } : ->(y) { f.(y) < f.(pivot) }
21
23
  less, more = xs.partition &smaller_than
@@ -23,6 +25,7 @@ module Functions
23
25
  end
24
26
 
25
27
  Quick_Sort = Quick_Sort_By.partial(nil)
28
+ # = Quick_Sort_By.partial(Identity)
26
29
 
27
30
  end
28
31
  end
@@ -1,3 +1,3 @@
1
1
  module Functions
2
- VERSION = "0.0.12"
2
+ VERSION = "0.0.14"
3
3
  end
@@ -1,49 +1,39 @@
1
- require_relative '../examples/prelude_usage'
2
- require_relative '../examples/prelude_meta_usage'
1
+ require_relative '../examples/prelude_lambda'
3
2
 
4
- include PreludeUsage
5
- include PreludeUsageWithDefs
3
+ include PreludeLambdaUsage
4
+ # include PreludeUsageWithDefs
6
5
 
7
6
  require 'benchmark'
8
7
 
9
8
  [10, 100, 1000, 10000].each do |n|
10
9
  Benchmark.bm(40) do |b|
11
10
  b.report("Sum_Of_Squares(n=#{n}): ") { (100000/n).times { Sum_Of_Squares.((1..n).to_a) } }
12
- b.report("sum_of_squares(n=#{n}): ") { (100000/n).times { sum_of_squares ((1..n).to_a) } }
13
11
  end
14
12
  end
15
13
 
16
14
  [10, 100, 1000, 10000].each do |n|
17
15
  Benchmark.bm(40) do |b|
18
16
  b.report("Average(n=#{n}): ") { (100000/n).times { Average.((1..n).to_a) } }
19
- b.report("average(n=#{n}): ") { (100000/n).times { average ((1..n).to_a) } }
20
17
  end
21
18
  end
22
19
 
23
20
  [10, 100, 1000, 10000].each do |n|
24
21
  Benchmark.bm(40) do |b|
25
22
  b.report("Sum.(n=#{n}): ") { (100000/n).times { Sum.((1..n).to_a) } }
26
- b.report("sum(n=#{n}): ") { (100000/n).times { sum((1..n).to_a) } }
27
- b.report("sum_bis(n=#{n}): ") { (100000/n).times { sum_bis((1..n).to_a) } }
28
- b.report("sum_tris(n=#{n}): ") { (100000/n).times { sum_tris((1..n).to_a) } }
29
- b.report("sum_quater(n=#{n}): ") { (100000/n).times { sum_quater((1..n).to_a) } }
30
23
  end
31
24
  end
32
25
 
33
26
  [10, 100, 1000].each do |n|
34
27
  random_array = (0..n).to_a.shuffle
35
28
  Benchmark.bm(40) do |b|
36
- b.report("lambda/merge_sort(n=#{n}): ") { (100000/n).times { Merge_Sort.(random_array) } }
37
- b.report("def/merge_sort(n=#{n}): ") { (100000/n).times { merge_sort(random_array) } }
29
+ b.report("Merge_Sort(n=#{n}): ") { (100000/n).times { Merge_Sort.(random_array) } }
38
30
  end
39
31
  end
40
32
 
41
33
  [10, 100, 1000].each do |n|
42
34
  random_array = (0..n).to_a.shuffle
43
35
  Benchmark.bm(40) do |b|
44
- b.report("lambda/quick_sort(n=#{n}): ") { (100000/n).times { Quick_Sort.(random_array) } }
45
- # b.report("lambda/quick_sort/nil(n=#{n}): ") { (100000/n).times { Quick_Sort_By.(nil, random_array) } } # the same by definition
46
- b.report("lambda/quick_sort/identity(n=#{n}): ") { (100000/n).times { Quick_Sort_By.(Id, random_array) } }
47
- b.report("def/quick_sort(n=#{n}): ") { (100000/n).times { quick_sort(random_array) } }
36
+ b.report("Quick_Sort(n=#{n}): ") { (100000/n).times { Quick_Sort.(random_array) } }
37
+ b.report("Quick_Sort/identity(n=#{n}): ") { (100000/n).times { Quick_Sort_By.(Id, random_array) } }
48
38
  end
49
39
  end
@@ -0,0 +1,76 @@
1
+ require 'functions/prelude_enumerable'
2
+
3
+ describe "enumerable" do
4
+
5
+ it "zip_map" do
6
+ [1,2,3].zip([2,3,4]).map { |a,b| a+b }.should eq([3,5,7])
7
+ [1,2,3].zip_map([2,3,4]) { |a,b| a+b }.should eq([3,5,7])
8
+ [1,2,3].zip_map([2,3,4],[0,1,0]) { |a,b,c| a+b+c }.should eq([3,6,7])
9
+ [1,2,3].zip_map([2,3,4]).with_index { |(a,b),n| a+b+n }.should eq([3,6,9])
10
+ end
11
+
12
+ it "transpose" do
13
+ [[1,2,3]].transpose.should eq([[1],[2],[3]])
14
+ [[1,2,3],[:a,:b,:c]].transpose.should eq([[1,:a],[2,:b],[3,:c]])
15
+ end
16
+
17
+ it "zip, unzip" do
18
+ ns = [1,2,3]
19
+ as = [:a,:b,:c]
20
+ ns.zip(as).unzip.should eq([ns, as])
21
+ end
22
+
23
+ it "split_in" do
24
+ [1,2,3].split_in(1).should eq([[1,2,3]])
25
+ [1,2,3].split_in(2).should eq([[1,2],[3]])
26
+ [1,2,3].split_in(3).should eq([[1],[2],[3]])
27
+ [1,2,3].split_in(4).should eq([[1],[2],[3],[]]) # do we want this ? length 3 ? or lenght 4 ?
28
+ [1,2,3].split_in_half.should eq([[1,2],[3]])
29
+ end
30
+
31
+ it "merge" do
32
+ # starts with ordered sets
33
+ [1,3,5].merge([3,4,8]).should eq([1,3,3,4,5,8])
34
+ [1,3,5].merge([2]).should eq([1,2,3,5])
35
+ [].merge([1,2,3]).should eq([1,2,3])
36
+ [1,2,3].merge([]).should eq([1,2,3])
37
+ [3,2,1].merge([4,2,1]) { |a,b| a > b }.should eq([4,3,2,2,1,1])
38
+ end
39
+
40
+ it "interleave" do
41
+ %w(sex druggs rock roll).interleave([", "," and "," & "]).join("").should eq("sex, druggs and rock & roll")
42
+ [3,1,4].interleave([:a,:d,:b]).should eq([3,:a,1,:d,4,:b])
43
+ [3,1,4].interleave([:a,:d]).should eq([3,:a,1,:d,4])
44
+ [3,1,4].interleave([:a]).should eq([3,:a,1,4])
45
+ [3,1,4].interleave([]).should eq([3,1,4])
46
+ end
47
+
48
+ it "zip_hash" do
49
+ ab = {a: 'a', b: 'b'}
50
+ ad = {a: 'a', d: 'd'}
51
+ cb = {c: 'c', b: 'b'}
52
+ ab.zip_hash_left(ad).should eq({a: ['a','a'], b:['b',nil]})
53
+ ab.zip_hash_left(cb).should eq({a: ['a',nil], b:['b','b']})
54
+ ad.zip_hash_left(cb).should eq({a: ['a',nil], d:['d',nil]})
55
+ ab.zip_hash_inner(ad).should eq({a:['a','a']})
56
+ ab.zip_hash_inner(cb).should eq({b:['b','b']})
57
+ ad.zip_hash_inner(cb).should eq({})
58
+ end
59
+
60
+ it "map_hash" do
61
+ ab = {a: 1, b: 2}
62
+ ab.map_hash { |x| x*2}.should eq({a: 2, b: 4})
63
+ ab.map_hash { |x| x.even? }.should eq({a: false, b: true})
64
+ end
65
+
66
+ it "counted_set" do
67
+ [1,2,3,2,2,1,2].counted_set.should eq({1 => 2, 2 => 4, 3 => 1})
68
+ ['a','b','a','d'].counted_set.should eq({'a' => 2, 'b' => 1, 'd' => 1})
69
+ end
70
+
71
+ it "grouped_by" do
72
+ [1,2,3,2,2,1,2].grouped_by { |x| x.odd? }.should eq([[1,3,1],[2,2,2,2]])
73
+ %w(some words are longer then others).grouped_by { |x| x.length > 3 }.should eq([%w(some words longer then others),%w(are)])
74
+ end
75
+
76
+ end
@@ -9,6 +9,12 @@ describe Functions::Prelude, "math" do
9
9
  Divide.([8,2,2]).should eq(8/2/2)
10
10
  end
11
11
 
12
+ it "power" do
13
+ Power.(2,3).should eq(9)
14
+ Power.(0,3).should eq(1)
15
+ Power.(3,2).should eq(8)
16
+ end
17
+
12
18
  it "knows about divisors" do
13
19
  IsDivisor.(8,2).should eq(true)
14
20
  IsDivisor.(8,3).should eq(false)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: functions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koen Handekyn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-21 00:00:00.000000000 Z
11
+ date: 2013-11-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: functional programming in ruby
14
14
  email:
@@ -24,27 +24,29 @@ files:
24
24
  - README.md
25
25
  - Rakefile
26
26
  - examples/prelude_lambda.rb
27
- - examples/prelude_meta.rb
28
27
  - examples/spec/prelude_lambda_spec.rb
29
- - examples/spec/prelude_meta_spec.rb
30
28
  - functions.gemspec
31
29
  - lib/functions.rb
30
+ - lib/functions/prelude_enumerable.rb
31
+ - lib/functions/prelude_enumerable/enumerable.rb
32
+ - lib/functions/prelude_enumerable/hash.rb
32
33
  - lib/functions/prelude_lambda.rb
33
34
  - lib/functions/prelude_lambda/basic.rb
34
35
  - lib/functions/prelude_lambda/ext.rb
35
36
  - lib/functions/prelude_lambda/math.rb
36
37
  - lib/functions/prelude_lambda/sorting.rb
37
- - lib/functions/prelude_meta.rb
38
38
  - lib/functions/shared/ext.rb
39
39
  - lib/functions/version.rb
40
+ - meta/meta_programming.rb
40
41
  - performance/prelude_performance.rb
42
+ - spec/prelude_enumerable_spec.rb
41
43
  - spec/prelude_lambda_math_spec.rb
42
44
  - spec/prelude_lambda_spec.rb
43
- - spec/prelude_meta_spec.rb
44
45
  - spec/spec_helper.rb
45
46
  - test/test_prelude_performance.rb
46
47
  homepage: https://github.com/koenhandekyn/functions
47
- licenses: []
48
+ licenses:
49
+ - MIT
48
50
  metadata: {}
49
51
  post_install_message:
50
52
  rdoc_options: []
@@ -52,24 +54,23 @@ require_paths:
52
54
  - lib
53
55
  required_ruby_version: !ruby/object:Gem::Requirement
54
56
  requirements:
55
- - - ! '>='
57
+ - - '>='
56
58
  - !ruby/object:Gem::Version
57
59
  version: '0'
58
60
  required_rubygems_version: !ruby/object:Gem::Requirement
59
61
  requirements:
60
- - - ! '>='
62
+ - - '>='
61
63
  - !ruby/object:Gem::Version
62
64
  version: '0'
63
65
  requirements: []
64
66
  rubyforge_project:
65
- rubygems_version: 2.1.9
67
+ rubygems_version: 2.0.6
66
68
  signing_key:
67
69
  specification_version: 4
68
70
  summary: functional programming in ruby
69
71
  test_files:
72
+ - spec/prelude_enumerable_spec.rb
70
73
  - spec/prelude_lambda_math_spec.rb
71
74
  - spec/prelude_lambda_spec.rb
72
- - spec/prelude_meta_spec.rb
73
75
  - spec/spec_helper.rb
74
76
  - test/test_prelude_performance.rb
75
- has_rdoc:
@@ -1,58 +0,0 @@
1
- require 'functions'
2
-
3
- module PreludeMetaUsage
4
-
5
- include Functions::PreludeMeta
6
-
7
- # returns x to the power of p
8
- def power(x, p) x ** p end
9
-
10
- # returns x^2
11
- def square(x) power(x, 2) end
12
-
13
- # returns the list of the squares
14
- def squares(a) map(a, :square) end
15
-
16
- define :squares_bis, as: { map: :square }
17
-
18
- # test
19
- # def_map :squares, :square
20
- # def_map :squares_tris, ->(x) { x**2 }
21
- # define :squares, as: { map: ->(x) { x**2 } }
22
-
23
- # returns all elements of an enumerable that are even
24
- define :evens, as: { filter: :even? }
25
-
26
- # def_filter :evens, :even?
27
-
28
- # filter :evens, :even?
29
-
30
- define :odds, as: { filter: :odd? }
31
-
32
- # def_filter :odds, ->(x) { ! x.even? }
33
-
34
- def sum_of_squares(a) compose(:sum, :squares, a) end
35
-
36
- define :sum_of_squares_bis, as: { compose: [:sum, :squares] }
37
-
38
- # compose :sum_of_squares, :sum, :squares
39
-
40
- def average_bis(a) after([:sum, :length], :divide, a) end
41
-
42
- define :average_tris, as: { :after => [ :sum_length, :divide ] }
43
-
44
- # after :average_quater, :sum_length, :divide
45
-
46
- def inc_with(f, n, m) m + f(f).(n) end
47
-
48
- def sum_of(f, a) a.inject(0) { |r, x| r + f(f).(x) } end
49
-
50
- def add(a,b) a+b end
51
-
52
- define :sum_bis, as: { foldl: [:add, 0]}
53
-
54
- # foldl :sum_bis, :add, 0
55
-
56
- # define foldl: [:add, 0], as: :sum_quater
57
-
58
- end
@@ -1,33 +0,0 @@
1
- require_relative '../prelude_meta'
2
-
3
- include PreludeMetaUsage
4
-
5
- describe PreludeMetaUsage, "basic meta prelude usage" do
6
-
7
- it "squares" do
8
- squares([1, 2, 3]).should == [1, 4, 9]
9
- squares_bis([1, 2, 3]).should == [1, 4, 9]
10
- end
11
-
12
- it "evens and odds" do
13
- evens([1, 2, 3, 4, 5]).should == [2, 4]
14
- odds([1, 2, 3, 4, 5]).should == [1, 3, 5]
15
- end
16
-
17
- it "takes sums of squares" do
18
- sum_of(:square, [2, 3, 1]).should == 2*2+3*3+1*1
19
- sum_of(->(x) { x*x }, [2, 3, 1]).should == 2*2+3*3+1*1
20
- sum_of_squares([2, 3, 4]).should == 2*2+3*3+4*4
21
- sum_of_squares_bis([2, 3, 4]).should == 2*2+3*3+4*4
22
- end
23
-
24
- it "takes sums by some variant definitions" do
25
- sum_bis([1, 2, 3]).should == 1+2+3
26
- end
27
-
28
- it "takes averages by some variant definitions" do
29
- average_bis([2, 3, 8]).should == 4
30
- average_tris([2, 3, 8]).should == 4
31
- end
32
-
33
- end
@@ -1,34 +0,0 @@
1
- require 'functions'
2
-
3
- include Functions::PreludeMeta
4
-
5
- describe Functions::PreludeMeta, "basic meta prelude usage" do
6
-
7
- it "sums" do
8
- sum([1, 2, 3]).should == 1+2+3
9
- end
10
-
11
- it "takes averages" do
12
- average([2, 3, 8]).should == 4
13
- end
14
-
15
- it "folds" do
16
- foldl(->(n, a) { n/a }, 1.0, [1.0, 2.0, 3.0]).should == 1.0/1.0/2.0/3.0
17
- foldr(->(n, a) { n/a }, 1.0, [1.0, 2.0, 3.0]).should == 1.0/3.0/2.0/1.0
18
- end
19
-
20
- it "mins and maxes" do
21
- min([1, 2, 3]).should == 1
22
- max([1, 2, 3]).should == 3
23
- end
24
-
25
- it "makes ranges" do
26
- from_to(2, 3).should == (2..3)
27
- from_one_to(3).should == (1..3)
28
- end
29
-
30
- it "intersects arrays" do
31
- intersect([[1, 2, 3], [2, 3, 4], [2, 3, 8]]).should == [2, 3]
32
- end
33
-
34
- end