scaruby 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/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2012 Kazuhiro Sera
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
@@ -0,0 +1,16 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby/seq'
4
+
5
+ module Enumerable
6
+
7
+ def method_missing(name, *args, &block)
8
+ result = Scaruby::Seq.new(self).send(name, *args, &block)
9
+ if result.is_a?(Scaruby::Seq) then
10
+ result.to_a
11
+ else
12
+ result
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby/map'
4
+
5
+ class Hash
6
+ def method_missing(name, *args, &block)
7
+ result = Scaruby::Map.new(self).send(name, *args, &block)
8
+ if result.is_a?(Scaruby::Map) then
9
+ result.to_hash
10
+ else
11
+ result
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,11 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby/core_ext/enumerable.rb'
4
+ require 'scaruby/core_ext/hash.rb'
5
+
6
+ module Scaruby
7
+ module CoreExt
8
+ end
9
+ end
10
+
11
+
data/lib/scaruby/map.rb CHANGED
@@ -59,9 +59,12 @@ module Scaruby
59
59
  def find(&predicate)
60
60
  Option.new(@hash.inject([false,[]]) {|z,kv|
61
61
  found, matched_kv = z[0], z[1]
62
- if found then z
63
- elsif yield kv[0], kv[1] then [true,kv]
64
- else [false,[]]
62
+ if found then
63
+ z
64
+ elsif yield kv[0], kv[1] then
65
+ [true,kv]
66
+ else
67
+ [false,[]]
65
68
  end
66
69
  }[1])
67
70
  end
@@ -99,9 +102,27 @@ module Scaruby
99
102
  end
100
103
 
101
104
  def map(&block)
105
+ #Map.new(Hash[*@hash.to_a.collect {|k,v| yield k, v }.flatten])
102
106
  Map.new(Hash[*@hash.to_a.map {|k,v| yield k, v }.flatten])
103
107
  end
104
108
 
109
+ def minus(*keys)
110
+ copied = @hash.dup
111
+ keys.each do |key|
112
+ copied.delete(key)
113
+ end
114
+ Map.new(copied)
115
+ end
116
+
117
+ def plus(elems)
118
+ copied = @hash.dup
119
+ elems.each do |elm|
120
+ k,v = elm[0], elm[1]
121
+ copied[k] = v
122
+ end
123
+ Map.new(copied)
124
+ end
125
+
105
126
  def mk_string(*args)
106
127
  case args.size
107
128
  when 0
@@ -109,7 +130,7 @@ module Scaruby
109
130
  when 1
110
131
  start_part, sep, end_part = '', args[0], ''
111
132
  when 2
112
- raise 'Illegal number of arguments'
133
+ raise 'Illegal number of arguments (2)'
113
134
  else
114
135
  start_part, sep, end_part = args[0], args[1], args[2]
115
136
  end
@@ -121,6 +142,16 @@ module Scaruby
121
142
  ! is_empty
122
143
  end
123
144
 
145
+ def updated(k, v)
146
+ copied = @hash.dup
147
+ copied[k] = v
148
+ Map.new(copied)
149
+ end
150
+
151
+ def unzip
152
+ Seq.new([@hash.keys,@hash.values])
153
+ end
154
+
124
155
  end
125
156
  end
126
157
 
@@ -18,8 +18,10 @@ module Scaruby
18
18
  end
19
19
 
20
20
  def get
21
- if is_defined then @value
22
- else raise NoSuchElementException
21
+ if is_defined then
22
+ @value
23
+ else
24
+ raise NoSuchElementException
23
25
  end
24
26
  end
25
27
 
data/lib/scaruby/seq.rb CHANGED
@@ -18,6 +18,18 @@ module Scaruby
18
18
  def to_a
19
19
  @array
20
20
  end
21
+
22
+ def corresponds(that, &predicate)
23
+ @array.zip(that).inject(true) {|still_matched,e|
24
+ if ! still_matched then
25
+ false
26
+ elsif yield e[0], e[1] then
27
+ true
28
+ else
29
+ false
30
+ end
31
+ }
32
+ end
21
33
 
22
34
  def count(&predicate)
23
35
  filter(&predicate).size
@@ -42,9 +54,12 @@ module Scaruby
42
54
  def drop_while(&predicate)
43
55
  Seq.new(@array.inject([false,[]]) {|passed,x|
44
56
  no_need_to_yield, result = passed[0], passed[1]
45
- if no_need_to_yield then [true, result.push(x)]
46
- elsif yield x then passed
47
- else [true, result.push(x)]
57
+ if no_need_to_yield then
58
+ [true, result.push(x)]
59
+ elsif yield x then
60
+ passed
61
+ else
62
+ [true, result.push(x)]
48
63
  end
49
64
  }[1])
50
65
  end
@@ -55,17 +70,22 @@ module Scaruby
55
70
  end
56
71
  this_end = @array.reverse.take(that.length).reverse
57
72
  this_end.zip(that).inject(true) {|all_matched,a|
58
- if ! all_matched then false
59
- elsif a.length != 2 then false
60
- else a[0] == a[1]
73
+ if ! all_matched then
74
+ false
75
+ elsif a.length != 2 then
76
+ false
77
+ else
78
+ a[0] == a[1]
61
79
  end
62
80
  }
63
81
  end
64
82
 
65
83
  def exists(&predicate)
66
84
  @array.inject(false) {|found,e|
67
- if found then true
68
- else yield e
85
+ if found then
86
+ true
87
+ else
88
+ yield e
69
89
  end
70
90
  }
71
91
  end
@@ -83,13 +103,16 @@ module Scaruby
83
103
  end
84
104
 
85
105
  def flat_map(&block)
86
- Seq.new(@array.inject([]) {|z,x|
106
+ Seq.new(@array.inject([]) {|z,x|
87
107
  applied = yield x
88
108
  if applied.is_a?(Enumerable) then
89
109
  applied.inject(z) {|z,elm| z.push(elm) }
90
- elsif applied.is_a?(Option) then
110
+ elsif applied.is_a?(Seq) then
111
+ applied.to_a.inject(z) {|z,elm| z.push(elm) }
112
+ elsif applied.is_a?(Option) then
91
113
  applied.is_defined ? z.push(applied.get) : z
92
- else z.push(applied)
114
+ else
115
+ z.push(applied)
93
116
  end
94
117
  })
95
118
  end
@@ -110,16 +133,35 @@ module Scaruby
110
133
  @array.inject(z) {|z,x| yield z, x }
111
134
  end
112
135
 
136
+ def fold_right(z, &block)
137
+ @array.reverse.inject(z) {|z,x| yield z, x }
138
+ end
139
+
113
140
  def forall(&predicate)
114
141
  @array.inject(true) {|all_matched,e|
115
- if ! all_matched then false
116
- else yield e
142
+ if ! all_matched then
143
+ false
144
+ else
145
+ yield e
117
146
  end
118
147
  }
119
148
  end
120
149
 
121
150
  def foreach(&block)
122
- @array.each do |e| yield e end
151
+ @array.each do |e|
152
+ yield e
153
+ end
154
+ end
155
+
156
+ def group_by(&block)
157
+ Map.new(@array.inject({}) {|z,e|
158
+ if z[e].nil? then
159
+ z[e] = [e]
160
+ else
161
+ z[e] = z[e].push(e)
162
+ end
163
+ z
164
+ })
123
165
  end
124
166
 
125
167
  def head
@@ -197,8 +239,10 @@ module Scaruby
197
239
 
198
240
  def partition(&predicate)
199
241
  Seq.new(@array.inject([[],[]]) {|z,x|
200
- if yield x then [z[0].push(x),z[1]]
201
- else [z[0],z[1].push(x)]
242
+ if yield x then
243
+ [z[0].push(x),z[1]]
244
+ else
245
+ [z[0],z[1].push(x)]
202
246
  end
203
247
  })
204
248
  end
@@ -221,9 +265,12 @@ module Scaruby
221
265
 
222
266
  def same_elements(that)
223
267
  @array.zip(that).inject(true) {|still_same,a|
224
- if ! still_same then false
225
- elsif a.length != 2 then false
226
- else a[0] == a[1]
268
+ if ! still_same then
269
+ false
270
+ elsif a.length != 2 then
271
+ false
272
+ else
273
+ a[0] == a[1]
227
274
  end
228
275
  }
229
276
  end
@@ -269,9 +316,12 @@ module Scaruby
269
316
  def span(&predicate)
270
317
  result = @array.inject([true,[],[]]) {|z,x|
271
318
  still_matched, first, second = z[0], z[1], z[2]
272
- if ! still_matched then [false,first,second.push(x)]
273
- elsif yield x then [true,first.push(x),second]
274
- else [false,first,second.push(x)]
319
+ if ! still_matched then
320
+ [false,first,second.push(x)]
321
+ elsif yield x then
322
+ [true,first.push(x),second]
323
+ else
324
+ [false,first,second.push(x)]
275
325
  end
276
326
  }
277
327
  Seq.new([result[1],result[2]])
@@ -287,9 +337,12 @@ module Scaruby
287
337
  end
288
338
  this_start = @array.take(that.length)
289
339
  this_start.zip(that).inject(true) {|all_matched,a|
290
- if ! all_matched then false
291
- elsif a.length != 2 then false
292
- else a[0] == a[1]
340
+ if ! all_matched then
341
+ false
342
+ elsif a.length != 2 then
343
+ false
344
+ else
345
+ a[0] == a[1]
293
346
  end
294
347
  }
295
348
  end
@@ -313,9 +366,12 @@ module Scaruby
313
366
  def take_while(&predicate)
314
367
  Seq.new(@array.inject([false,[]]) {|passed,x|
315
368
  is_already_unmatched, result = passed[0], passed[1]
316
- if is_already_unmatched then passed
317
- elsif yield x then [false,result.push(x)]
318
- else [true, result]
369
+ if is_already_unmatched then
370
+ passed
371
+ elsif yield x then
372
+ [false,result.push(x)]
373
+ else
374
+ [true, result]
319
375
  end
320
376
  }[1])
321
377
  end
@@ -324,13 +380,19 @@ module Scaruby
324
380
  Seq.new(@array.concat(that))
325
381
  end
326
382
 
383
+ def updated(idx, elm)
384
+ Seq.new(@array.fill(elm,idx,1))
385
+ end
386
+
327
387
  def zip(that)
328
388
  Seq.new(@array.zip(that).select {|a,b| ! a.nil? && ! b.nil? })
329
389
  end
330
390
 
331
391
  def zip_with_index
332
392
  with_index = []
333
- @array.each_with_index do |v,idx| with_index.push([v,idx]) end
393
+ @array.each_with_index do |v,idx|
394
+ with_index.push([v,idx])
395
+ end
334
396
  with_index
335
397
  end
336
398
 
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  module Scaruby
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
6
6
 
data/readme.md CHANGED
@@ -1,15 +1,20 @@
1
- # Ruby reference for Scala programmers
1
+ # Scala API in Ruby
2
2
 
3
- Surely it works fine. But it mainly serves as a Ruby reference for Scala programmers.
3
+ Surely it works fine.
4
4
 
5
- ## Setup
5
+ But it mainly serves as a Ruby reference for Scala programmers.
6
+
7
+ ## Gemfile
6
8
 
7
- ```sh
8
- git clone git://github.com/seratch/scaruby.git
9
- cd scaruby
10
- gem install bundler
11
- bundle install
12
9
  ```
10
+ source "http://rubygems.org/"
11
+
12
+ gem 'scaruby'
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ See specs.
13
18
 
14
19
  ## Trying on irb
15
20
 
@@ -18,36 +23,51 @@ bundle console
18
23
  ```
19
24
 
20
25
  ```ruby
21
- irb(main):001:0> require 'scaruby'
26
+ irb(main):008:0> require 'scaruby'
22
27
  => false
23
28
 
24
- irb(main):003:0> Option.new(nil).is_defined
29
+ irb(main):009:0> Option.new(nil).is_defined
30
+ => false
31
+ irb(main):010:0> Option.apply(nil).is_defined
25
32
  => false
26
- irb(main):004:0> Option.new(123).is_defined
33
+ irb(main):011:0> Option.new(123).is_defined
27
34
  => true
28
35
 
29
- irb(main):004:0> Seq.new([1,2,3]).map {|e| e * e }
30
- => #<Scaruby::Seq:0x9dca2e0 @enumerable=[1, 4, 9]>
31
- irb(main):005:0> Seq.new([1,2,3]).map {|e| e * e }.to_a
32
- => [1, 4, 9]
33
-
34
- irb(main):004:0> Seq.new([1,2,3]).filter {|e| e < 2 }.to_a
36
+ irb(main):012:0> Seq.new([1,2,3]).filter {|e| e < 2 }
37
+ => #<Scaruby::Seq:0x9772424 @array=[1]>
38
+ irb(main):013:0> Seq.new([1,2,3]).filter {|e| e < 2 }.to_a
35
39
  => [1]
40
+ irb(main):014:0> Seq.new([1,2,3]).fold_left(0) {|z,x| z + x }
41
+ => 6
36
42
 
37
- irb(main):002:0> Seq.new([[1,2,3],[4,5],[6]]).flat_map {|e| e }.to_a
38
- => [1, 2, 3, 4, 5, 6]
43
+ irb(main):025:0> Map.new({123=>'abc',23=>'bc',345=>'cde'}).filter {|k,v| k.to_s.size == 3 }
44
+ => #<Scaruby::Map:0x94afa98 @hash={123=>"abc", 345=>"cde"}>
45
+ irb(main):026:0> Map.new({123=>'abc',23=>'bc',345=>'cde'}).filter {|k,v| k.to_s.size == 3 }.to_hash
46
+ => {123=>"abc", 345=>"cde"}
47
+ ```
39
48
 
40
- irb(main):003:0> Seq.new([1,2,3]).fold_left(0) {|z,x| z + x }
41
- => 6
49
+ You can extend Ruby with Scaruby. If the method is missing, the method in Scaruby will be invoked.
50
+
51
+ Already defined methods (i.e. flat_map, find and so on) are never replaced.
42
52
 
43
- irb(main):001:0> require 'enumerable_to_scaruby'
53
+ ```ruby
54
+ irb(main):015:0> require 'scaruby/core_ext'
44
55
  => true
45
- irb(main):002:0> [[1,2,3],[4,5],[6]].flat_map {|e| e }
46
- => [1, 2, 3, 4, 5, 6]
56
+ irb(main):016:0> 1.upto(5).filter {|i| i < 3 }
57
+ => [1, 2]
58
+ irb(main):020:0> 1.upto(5).filter {|i| i < 3 }.foreach do |i|
59
+ irb(main):021:1* puts i
60
+ irb(main):022:1> end
61
+ 1
62
+ 2
63
+ => [1, 2]
64
+
65
+ irb(main):027:0> {123=>'abc',23=>'bc',345=>'cde'}.filter {|k,v| k.to_s.size == 3 }
66
+ => {123=>"abc", 345=>"cde"}
47
67
  ```
48
68
 
49
- ## Testing
69
+ ## License
70
+
71
+ MIT License
72
+
50
73
 
51
- ```sh
52
- bundle exec rspec
53
- ```
@@ -0,0 +1,288 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby/core_ext'
4
+
5
+ describe Seq do
6
+
7
+ one_to_five = 1.upto 5
8
+ one_to_five_shuffled = one_to_five.sort_by {rand}
9
+
10
+ it 'has #to_a' do
11
+ (one_to_five).to_a.should eq([1,2,3,4,5])
12
+ end
13
+ it 'has #corresponds' do
14
+ ([1,2,3]).corresponds([1,2,3]) {|a,b| a == b }.should eq(true)
15
+ ([1,2,3]).corresponds([3,1,2]) {|a,b| a == b }.should eq(false)
16
+ end
17
+ it 'has #count' do
18
+ (one_to_five).count {|i| i > 2 }.should eq(3)
19
+ end
20
+ it 'has #diff' do
21
+ ([1,2,3]).diff([2,3,4]).to_a.should eq([1])
22
+ end
23
+ it 'has #distinct' do
24
+ ([1,2,4,1,3,3,3,2,4,1]).distinct.to_a.should eq([1,2,4,3])
25
+ end
26
+ it 'has #drop' do
27
+ (one_to_five).drop(3).to_a.should eq([4,5])
28
+ (one_to_five).drop(7).to_a.should eq([])
29
+ end
30
+ it 'has #drop_right' do
31
+ (one_to_five).drop_right(3).to_a.should eq([1,2])
32
+ (one_to_five).drop_right(7).to_a.should eq([])
33
+ end
34
+ it 'has #drop_while' do
35
+ ([5,3,2,4,1]).drop_while {|e| e > 2 }.to_a.should eq([2,4,1])
36
+ end
37
+ it 'has #ends_with' do
38
+ ([1,2,3]).ends_with([1,2]).should eq(false)
39
+ ([1,2,3]).ends_with([1,2,3]).should eq(true)
40
+ ([1,2,3]).ends_with([1,1,2,3]).should eq(false)
41
+ ([1,2,3]).ends_with([2,3]).should eq(true)
42
+ ([1,2,3]).ends_with([3]).should eq(true)
43
+ end
44
+ it 'has #exists' do
45
+ ([1,2,3]).exists {|i| i < 2 }.should eq(true)
46
+ ([1,2,3]).exists {|i| i < 4 }.should eq(true)
47
+ ([2,3,4]).exists {|i| i > 4 }.should eq(false)
48
+ end
49
+ it 'has #filter' do
50
+ (one_to_five).filter {|i| i > 3 }.to_a.should eq([4,5])
51
+ (one_to_five).filter {|i| i > 10 }.to_a.should eq([])
52
+ end
53
+ it 'has #filter_not' do
54
+ (one_to_five).filter_not {|i| i > 3 }.to_a.should eq([1,2,3])
55
+ (one_to_five).filter_not {|i| i > 10 }.to_a.should eq([1,2,3,4,5])
56
+ end
57
+ it 'has #find' do
58
+ some = (one_to_five).find {|i| i < 3 }
59
+ # the already defined method is called
60
+ #some.get.should eq(1)
61
+ some.should eq(1)
62
+ none = (one_to_five).find {|i| i > 10 }
63
+ # the already defined method is called
64
+ #none.is_defined.should eq(false)
65
+ none.should eq(nil)
66
+ end
67
+ it 'has #flat_map and it works with nested arrays' do
68
+ ([[1,2],[3,4],[5]]).flat_map {|i| i }.to_a.should eq([1,2,3,4,5])
69
+ end
70
+ it 'has #flat_map and it works with Option elements' do
71
+ # the already defined method is called
72
+ #([1,2,nil,3]).flat_map {|i| Option.new(i) }.to_a.should eq([1,2,3])
73
+ [1,2,nil,3].flat_map {|i| Option.new(i) }.to_a do |opt|
74
+ opt.is_a?(Option).should eq(true)
75
+ end
76
+ end
77
+ it 'has #fold_left' do
78
+ input = [1,2,3]
79
+ expected = [1,2,3]
80
+ idx = 0
81
+ (input).fold_left(0) {|z,x|
82
+ x.should eq(expected[idx])
83
+ idx += 1
84
+ z + x
85
+ }.should eq(6)
86
+ end
87
+ it 'has #fold_right' do
88
+ input = [1,2,3]
89
+ expected = [3,2,1]
90
+ idx = 0
91
+ (input).fold_right(0) {|z,x|
92
+ x.should eq(expected[idx])
93
+ idx += 1
94
+ z + x
95
+ }.should eq(6)
96
+ end
97
+ it 'has #flatten' do
98
+ ([[1,2],[3,4],[5]]).flatten.to_a.should eq([1,2,3,4,5])
99
+ ([Option.new(1),
100
+ Option.new(2),
101
+ Option.new(nil),
102
+ Option.new(3)]
103
+ ).flatten.to_a.each do |opt|
104
+ opt.is_a?(Option).should eq(true)
105
+ end
106
+ end
107
+ it 'has #forall' do
108
+ ([1,2,3]).forall {|i| i > 0 }.should eq(true)
109
+ ([1,2,3]).forall {|i| i > 1 }.should eq(false)
110
+ end
111
+ it 'has #foreach' do
112
+ count = 0
113
+ ([1,2,3]).foreach do |i|
114
+ count += 1
115
+ end
116
+ count.should eq(3)
117
+ end
118
+ it 'has #group_by' do
119
+ expected = {3=>[3,3,3], 1=>[1,1,1], 2=>[2,2]}
120
+ ([1,1,1,2,3,2,3,3]).group_by {|i| i }.to_hash.should eq(expected)
121
+ end
122
+ it 'has #head' do
123
+ (one_to_five).head.should eq(1)
124
+ end
125
+ it 'has #head_option and it works with Some' do
126
+ some = (one_to_five).head_option
127
+ some.get_or_else(999).should eq(1)
128
+ end
129
+ it 'has #head_option and it works with None' do
130
+ none = ([]).head_option
131
+ none.get_or_else(999).should eq(999)
132
+ end
133
+ it 'has #indices' do
134
+ ([1,2,3]).indices.to_a.should eq([0,1,2])
135
+ end
136
+ it 'has #init' do
137
+ ([1,2,3]).init.to_a.should eq([1,2])
138
+ end
139
+ it 'has #intersect' do
140
+ ([1,2,3]).intersect([2,3,4]).to_a.should eq([2,3])
141
+ end
142
+ it 'has #is_empty' do
143
+ ([1,2,3]).is_empty.should eq(false)
144
+ ([nil]).is_empty.should eq(false)
145
+ ([]).is_empty.should eq(true)
146
+ end
147
+ it 'has #last' do
148
+ ([1,2,3]).last.should eq(3)
149
+ end
150
+ it 'has #last_option' do
151
+ some = ([1,2,3]).last_option
152
+ some.get.should eq(3)
153
+ none = ([]).last_option
154
+ none.is_defined.should eq(false)
155
+ end
156
+ it 'has #lift' do
157
+ seq_lift = ([1,2,3]).lift
158
+ seq_lift.apply(0).get.should eq(1)
159
+ seq_lift.apply(1).get.should eq(2)
160
+ seq_lift.apply(2).get.should eq(3)
161
+ seq_lift.apply(3).is_defined.should eq(false)
162
+ seq_lift.call(0).get.should eq(1)
163
+ seq_lift.call(1).get.should eq(2)
164
+ seq_lift.call(2).get.should eq(3)
165
+ seq_lift.call(3).is_defined.should eq(false)
166
+ end
167
+ it 'has #map' do
168
+ ([1,2,3]).map {|i| i + i }.to_a.should eq([2,4,6])
169
+ end
170
+ it 'has #max' do
171
+ (one_to_five_shuffled).max.should eq(5)
172
+ end
173
+ it 'has #min' do
174
+ (one_to_five_shuffled).min.should eq(1)
175
+ end
176
+ it 'has #mk_string' do
177
+ (one_to_five).mk_string.should eq('12345')
178
+ (one_to_five).mk_string(',').should eq('1,2,3,4,5')
179
+ (one_to_five).mk_string('^',',','$').should eq('^1,2,3,4,5$')
180
+ begin
181
+ (one_to_five).mk_string('a','b').should eq(nil)
182
+ rescue ArgumentError
183
+ end
184
+ (one_to_five).mk_string('^',',','$','zzz').should eq('^1,2,3,4,5$')
185
+ end
186
+ it 'has #non_empty' do
187
+ (one_to_five).non_empty.should eq(true)
188
+ ([]).non_empty.should eq(false)
189
+ end
190
+ it 'has #partition' do
191
+ ([5,2,3,1,4,2,3]).partition {|i| i < 3 }.to_a.should eq([[2,1,2],[5,3,4,3]])
192
+ end
193
+ it 'has #patch' do
194
+ ([5,2,3,1,4,2,3]).patch(3,[111,222],3).to_a.should eq([5,2,3,111,222,3])
195
+ end
196
+ it 'has #reverse' do
197
+ ([1,2,3]).reverse.to_a.should eq([3,2,1])
198
+ end
199
+ it 'has #reverse_map' do
200
+ ([1,2,3]).reverse_map {|i| i + i }.to_a.should eq([6,4,2])
201
+ end
202
+ it 'has #same_elements' do
203
+ ([1,2,3]).same_elements([1,2,3]).should eq(true)
204
+ ([1,2,3]).same_elements([1,3,2]).should eq(false)
205
+ ([1,2,3]).same_elements([1,2]).should eq(false)
206
+ end
207
+ it 'has #scan_left' do
208
+ ([1,2,3]).scan_left(1) {|a,b| a + b }.to_a.should eq([1,2,4,7])
209
+ end
210
+ it 'has #scan_right' do
211
+ ([1,2,3]).scan_right(1) {|a,b| a + b }.to_a.should eq([7,6,4,1])
212
+ end
213
+ it 'has #slice' do
214
+ # the already defined method is called
215
+ #[1,2,3,4,5].slice(1,1).to_a.should eq([])
216
+ #[1,2,3,4,5].slice(1,2).to_a.should eq([2])
217
+ #[1,2,3,4,5].slice(1,3).to_a.should eq([2,3])
218
+ #[1,2,3,4,5].slice(1,4).to_a.should eq([2,3,4])
219
+ [1,2,3,4,5].slice(1,1).should eq([2])
220
+ [1,2,3,4,5].slice(1,2).should eq([2,3])
221
+ [1,2,3,4,5].slice(1,3).should eq([2,3,4])
222
+ [1,2,3,4,5].slice(1,4).should eq([2,3,4,5])
223
+ end
224
+ it 'has #sliding' do
225
+ ([1,2,3,4,5]).sliding(2).to_a.should eq([[1,2],[2,3],[3,4],[4,5]])
226
+ end
227
+ it 'has #sort_with' do
228
+ ([1,3,2,4,5]).sort_with {|a,b| b <=> a }.to_a.should eq([5,4,3,2,1])
229
+ end
230
+ it 'has #span' do
231
+ ([1,2,3,2,1]).span {|i| i < 3 }.to_a.should eq([[1,2],[3,2,1]])
232
+ end
233
+ it 'has #split_at' do
234
+ ([1,2,3,2,1]).split_at(3).to_a.should eq([[1,2,3],[2,1]])
235
+ end
236
+ it 'has #starts_with' do
237
+ ([1,2,3]).starts_with([1]).should eq(true)
238
+ ([1,2,3]).starts_with([1,2]).should eq(true)
239
+ ([1,2,3]).starts_with([1,2,3]).should eq(true)
240
+ ([1,2,3]).starts_with([1,2,3,4]).should eq(false)
241
+ ([1,2,3]).starts_with([2,3]).should eq(false)
242
+ ([1,2,3]).starts_with([4,1,2,3]).should eq(false)
243
+ end
244
+ it 'has #sum' do
245
+ ([1,2,3]).sum.should eq(6)
246
+ end
247
+ it 'has #tail' do
248
+ ([1,2,3]).tail.to_a.should eq([2,3])
249
+ ([]).tail.to_a.should eq([])
250
+ end
251
+ it 'has #take' do
252
+ ([1,2,3]).take(0).to_a.should eq([])
253
+ ([1,2,3]).take(1).to_a.should eq([1])
254
+ ([1,2,3]).take(2).to_a.should eq([1,2])
255
+ ([1,2,3]).take(3).to_a.should eq([1,2,3])
256
+ ([1,2,3]).take(4).to_a.should eq([1,2,3])
257
+ end
258
+ it 'has #take_right' do
259
+ ([1,2,3]).take_right(0).to_a.should eq([])
260
+ ([1,2,3]).take_right(1).to_a.should eq([3])
261
+ ([1,2,3]).take_right(2).to_a.should eq([2,3])
262
+ ([1,2,3]).take_right(3).to_a.should eq([1,2,3])
263
+ ([1,2,3]).take_right(4).to_a.should eq([1,2,3])
264
+ end
265
+ it 'has #take_while' do
266
+ ([5,3,2,4,1]).take_while {|e| e > 2 }.to_a.should eq([5,3])
267
+ end
268
+ it 'has #union' do
269
+ ([1,2,3]).union([2,3,4]).to_a.should eq([1,2,3,2,3,4])
270
+ end
271
+ it 'has #updated' do
272
+ ([1,2,3]).updated(1,999).to_a.should eq([1,999,3])
273
+ end
274
+ it 'has #zip' do
275
+ # the already defined method is called
276
+ #[1,2,3].zip([2,3]).to_a.should eq([[1,2],[2,3]])
277
+ #[1,2,3].zip([2,3,4]).to_a.should eq([[1,2],[2,3],[3,4]])
278
+ #[1,2,3].zip([2,3,4,5]).to_a.should eq([[1,2],[2,3],[3,4]])
279
+ [1,2,3].zip([2,3]).should eq([[1,2],[2,3],[3,nil]])
280
+ [1,2,3].zip([2,3,4]).should eq([[1,2],[2,3],[3,4]])
281
+ [1,2,3].zip([2,3,4,5]).should eq([[1,2],[2,3],[3,4]])
282
+ end
283
+ it 'has #zip_with_index' do
284
+ ([]).zip_with_index.to_a.should eq([])
285
+ ([1,2,3]).zip_with_index.to_a.should eq([[1,0],[2,1],[3,2]])
286
+ end
287
+
288
+ end
@@ -0,0 +1,92 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby/core_ext'
4
+
5
+ describe Map do
6
+
7
+ hash = {123 => 'abc', 234 => 'bcd', 345 => 'cde', 4 => 'd', 56 => 'ef', 7 => 'g', 89 => 'hi' }
8
+
9
+ it 'has #contains' do
10
+ (hash).contains(123).should eq(true)
11
+ (hash).contains(999).should eq(false)
12
+ end
13
+ it 'has #count' do
14
+ (hash).count {|k,v| k.to_s.length >= 2 }.should eq(5)
15
+ end
16
+ it 'hash Map.empty' do
17
+ Map.empty.should eq({})
18
+ end
19
+ it 'has #exists' do
20
+ (hash).exists {|k,v| k.to_s.length == 1 }.should eq(true)
21
+ end
22
+ it 'has #filter' do
23
+ (hash).filter {|k,v| k.to_s.length < 3 }.to_hash.size.should eq(4)
24
+ end
25
+ it 'has #filter_keys' do
26
+ (hash).filter_keys {|k| k.to_s.length < 3 }.to_hash.size.should eq(4)
27
+ end
28
+ it 'has #filter_not' do
29
+ (hash).filter_not {|k| k.to_s.length < 3 }.to_hash.to_s.should eq('{123=>"abc", 234=>"bcd", 345=>"cde"}')
30
+ end
31
+ it 'has #find' do
32
+ # the already defined method is called
33
+ #(hash).find {|k,v| k.to_s.length == 2 }.get[1].should eq('ef')
34
+ (hash).find {|k,v| k.to_s.length == 2 }[1].should eq('ef')
35
+ end
36
+ it 'has #forall' do
37
+ (hash).forall {|k,v| k.to_s.length <= 3 }.should eq(true)
38
+ (hash).forall {|k,v| k.to_s.length >= 2 }.should eq(false)
39
+ end
40
+ it 'has #foreach' do
41
+ (hash).foreach do |k,v|
42
+ hash.include?(k).should eq(true)
43
+ end
44
+ end
45
+ it 'has #get_or_else' do
46
+ (hash).get_or_else(123, 'xxx').should eq('abc')
47
+ (hash).get_or_else(999, 'xxx').should eq('xxx')
48
+ end
49
+ it 'has #is_empty' do
50
+ (hash).is_empty.should eq(false)
51
+ ({}).is_empty.should eq(true)
52
+ end
53
+ it 'has #key_set' do
54
+ (hash).key_set.should eq(hash.keys)
55
+ end
56
+ it 'has #lift' do
57
+ lifted = (hash).lift
58
+ lifted.apply(123).get.should eq('abc')
59
+ lifted.apply(999).is_defined.should eq(false)
60
+ lifted.call(123).get.should eq('abc')
61
+ lifted.call(999).is_defined.should eq(false)
62
+ end
63
+ it 'has #map' do
64
+ # the already defined method is called
65
+ #new_map = (hash).map {|k,v| [k+k,v] }.to_hash
66
+ #new_map.include?(246).should eq(true)
67
+ seq = (hash).map {|k,v| [k+k,v] }
68
+ seq.include?([246,'abc']).should eq(true)
69
+ end
70
+ it 'has #minus' do
71
+ (hash).minus(123,234,345).to_hash.should eq({4=>'d',56=>'ef',7=>'g',89=>'hi'})
72
+ end
73
+ it 'has #mk_string' do
74
+ (hash).mk_string().should eq('{123=>abc, 234=>bcd, 345=>cde, 4=>d, 56=>ef, 7=>g, 89=>hi}')
75
+ end
76
+ it 'has #non_empty' do
77
+ (hash).non_empty.should eq(true)
78
+ ({}).non_empty.should eq(false)
79
+ end
80
+ it 'has #plus' do
81
+ ({123=>'abc',234=>'bcd'}).plus([[345,'cde']]).to_hash.should eq({123=>'abc',234=>'bcd',345=>'cde'})
82
+ end
83
+ it 'has #updated' do
84
+ ({123=>'abc',234=>'bcd'}).updated(345,'cde').to_hash.should eq({123=>'abc',234=>'bcd',345=>'cde'})
85
+ end
86
+ it 'has #unzip' do
87
+ unzipped = ({123=>'abc',234=>'bcd'}).unzip.to_a
88
+ unzipped[0].should eq([123,234])
89
+ unzipped[1].should eq(['abc','bcd'])
90
+ end
91
+ end
92
+
@@ -67,6 +67,9 @@ describe Map do
67
67
  new_map = Map.new(hash).map {|k,v| [k+k,v] }.to_hash
68
68
  new_map.include?(246).should eq(true)
69
69
  end
70
+ it 'has #minus' do
71
+ Map.new(hash).minus(123,234,345).to_hash.should eq({4=>'d',56=>'ef',7=>'g',89=>'hi'})
72
+ end
70
73
  it 'has #mk_string' do
71
74
  Map.new(hash).mk_string().should eq('{123=>abc, 234=>bcd, 345=>cde, 4=>d, 56=>ef, 7=>g, 89=>hi}')
72
75
  end
@@ -75,7 +78,16 @@ describe Map do
75
78
  Map.new({}).non_empty.should eq(false)
76
79
  Map.new(nil).non_empty.should eq(false)
77
80
  end
81
+ it 'has #plus' do
82
+ Map.new({123=>'abc',234=>'bcd'}).plus([[345,'cde']]).to_hash.should eq({123=>'abc',234=>'bcd',345=>'cde'})
83
+ end
84
+ it 'has #updated' do
85
+ Map.new({123=>'abc',234=>'bcd'}).updated(345,'cde').to_hash.should eq({123=>'abc',234=>'bcd',345=>'cde'})
86
+ end
87
+ it 'has #unzip' do
88
+ unzipped = Map.new({123=>'abc',234=>'bcd'}).unzip.to_a
89
+ unzipped[0].should eq([123,234])
90
+ unzipped[1].should eq(['abc','bcd'])
91
+ end
78
92
  end
79
93
 
80
-
81
-
@@ -20,6 +20,10 @@ describe Seq do
20
20
  it 'has #to_a' do
21
21
  Seq.new(one_to_five).to_a.should eq([1,2,3,4,5])
22
22
  end
23
+ it 'has #corresponds' do
24
+ Seq.new([1,2,3]).corresponds([1,2,3]) {|a,b| a == b }.should eq(true)
25
+ Seq.new([1,2,3]).corresponds([3,1,2]) {|a,b| a == b }.should eq(false)
26
+ end
23
27
  it 'has #count' do
24
28
  Seq.new(one_to_five).count {|i| i > 2 }.should eq(3)
25
29
  end
@@ -63,8 +67,8 @@ describe Seq do
63
67
  it 'has #find' do
64
68
  some = Seq.new(one_to_five).find {|i| i < 3 }
65
69
  some.get.should eq(1)
66
- some = Seq.new(one_to_five).find {|i| i > 10 }
67
- some.is_defined.should eq(false)
70
+ none = Seq.new(one_to_five).find {|i| i > 10 }
71
+ none.is_defined.should eq(false)
68
72
  end
69
73
  it 'has #flat_map and it works with nested arrays' do
70
74
  Seq.new([[1,2],[3,4],[5]]).flat_map {|i| i }.to_a.should eq([1,2,3,4,5])
@@ -73,7 +77,24 @@ describe Seq do
73
77
  Seq.new([1,2,nil,3]).flat_map {|i| Option.new(i) }.to_a.should eq([1,2,3])
74
78
  end
75
79
  it 'has #fold_left' do
76
- Seq.new(one_to_five_shuffled).fold_left(0) {|z,x| z + x }.should eq(15)
80
+ input = [1,2,3]
81
+ expected = [1,2,3]
82
+ idx = 0
83
+ Seq.new(input).fold_left(0) {|z,x|
84
+ x.should eq(expected[idx])
85
+ idx += 1
86
+ z + x
87
+ }.should eq(6)
88
+ end
89
+ it 'has #fold_right' do
90
+ input = [1,2,3]
91
+ expected = [3,2,1]
92
+ idx = 0
93
+ Seq.new(input).fold_right(0) {|z,x|
94
+ x.should eq(expected[idx])
95
+ idx += 1
96
+ z + x
97
+ }.should eq(6)
77
98
  end
78
99
  it 'has #flatten' do
79
100
  Seq.new([[1,2],[3,4],[5]]).flatten.to_a.should eq([1,2,3,4,5])
@@ -95,6 +116,10 @@ describe Seq do
95
116
  end
96
117
  count.should eq(3)
97
118
  end
119
+ it 'has #group_by' do
120
+ expected = {3=>[3,3,3], 1=>[1,1,1], 2=>[2,2]}
121
+ Seq.new([1,1,1,2,3,2,3,3]).group_by {|i| i }.to_hash.should eq(expected)
122
+ end
98
123
  it 'has #head' do
99
124
  Seq.new(one_to_five).head.should eq(1)
100
125
  end
@@ -171,15 +196,9 @@ describe Seq do
171
196
  it 'has #patch' do
172
197
  Seq.new([5,2,3,1,4,2,3]).patch(3,[111,222],3).to_a.should eq([5,2,3,111,222,3])
173
198
  end
174
- it 'has #reduce_left' do
175
- end
176
- it 'has #reduce_right' do
177
- end
178
199
  it 'has #reverse' do
179
200
  Seq.new([1,2,3]).reverse.to_a.should eq([3,2,1])
180
201
  end
181
- it 'has #reverse_iterator' do
182
- end
183
202
  it 'has #reverse_map' do
184
203
  Seq.new([1,2,3]).reverse_map {|i| i + i }.to_a.should eq([6,4,2])
185
204
  end
@@ -247,6 +266,9 @@ describe Seq do
247
266
  it 'has #union' do
248
267
  Seq.new([1,2,3]).union([2,3,4]).to_a.should eq([1,2,3,2,3,4])
249
268
  end
269
+ it 'has #updated' do
270
+ Seq.new([1,2,3]).updated(1,999).to_a.should eq([1,999,3])
271
+ end
250
272
  it 'has #zip' do
251
273
  Seq.new([1,2,3]).zip([2,3]).to_a.should eq([[1,2],[2,3]])
252
274
  Seq.new([1,2,3]).zip([2,3,4]).to_a.should eq([[1,2],[2,3],[3,4]])
@@ -256,8 +278,5 @@ describe Seq do
256
278
  Seq.new([]).zip_with_index.to_a.should eq([])
257
279
  Seq.new([1,2,3]).zip_with_index.to_a.should eq([[1,0],[2,1],[3,2]])
258
280
  end
259
- end
260
-
261
-
262
-
263
281
 
282
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: scaruby
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Kazuhiro Sera
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-03-02 00:00:00 Z
13
+ date: 2012-03-03 00:00:00 Z
14
14
  dependencies: []
15
15
 
16
16
  description: Scala API in Ruby
@@ -25,11 +25,13 @@ extra_rdoc_files: []
25
25
  files:
26
26
  - .gitignore
27
27
  - Gemfile
28
+ - LICENSE.txt
28
29
  - Rakefile
29
- - lib/array_to_scaruby.rb
30
- - lib/enumerable_to_scaruby.rb
31
30
  - lib/scaruby.rb
32
31
  - lib/scaruby/appliable_proc.rb
32
+ - lib/scaruby/core_ext.rb
33
+ - lib/scaruby/core_ext/enumerable.rb
34
+ - lib/scaruby/core_ext/hash.rb
33
35
  - lib/scaruby/map.rb
34
36
  - lib/scaruby/no_such_element_exception.rb
35
37
  - lib/scaruby/option.rb
@@ -37,8 +39,8 @@ files:
37
39
  - lib/scaruby/version.rb
38
40
  - readme.md
39
41
  - scaruby.gemspec
40
- - spec/array_to_scaruby_spec.rb
41
- - spec/enumerable_to_scaruby_spec.rb
42
+ - spec/scaruby/core_ext/enumerable_spec.rb
43
+ - spec/scaruby/core_ext/hash_spec.rb
42
44
  - spec/scaruby/map_spec.rb
43
45
  - spec/scaruby/option_spec.rb
44
46
  - spec/scaruby/seq_spec.rb
@@ -71,8 +73,8 @@ signing_key:
71
73
  specification_version: 3
72
74
  summary: Scala API in Ruby
73
75
  test_files:
74
- - spec/array_to_scaruby_spec.rb
75
- - spec/enumerable_to_scaruby_spec.rb
76
+ - spec/scaruby/core_ext/enumerable_spec.rb
77
+ - spec/scaruby/core_ext/hash_spec.rb
76
78
  - spec/scaruby/map_spec.rb
77
79
  - spec/scaruby/option_spec.rb
78
80
  - spec/scaruby/seq_spec.rb
@@ -1,10 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- require 'scaruby/seq'
4
-
5
- class Array
6
- def method_missing(name, *args, &block)
7
- Scaruby::Seq.new(self).send(name, *args, &block)
8
- end
9
- end
10
-
@@ -1,10 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- require 'scaruby/seq'
4
-
5
- module Enumerable
6
- def method_missing(name, *args, &block)
7
- Scaruby::Seq.new(self).send(name, *args, &block)
8
- end
9
- end
10
-
@@ -1,23 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- require 'array_to_scaruby'
4
-
5
- describe Array do
6
- it 'has #flat_map' do
7
- flatten = [[1,2],[3],[4,5]].flat_map {|i| i }.to_a
8
- flatten.should eq([1,2,3,4,5])
9
- end
10
- it 'has #count' do
11
- result = [1,2,3,4,5].count {|i| i > 2 }
12
- result.should eq(3)
13
- end
14
- it 'has #diff' do
15
- result = [1,2,3].diff([2,3,4]).to_a
16
- result.should eq([1])
17
- end
18
- it 'has #distinct' do
19
- result = [1,2,4,1,3,3,3,2,4,1].distinct.to_a
20
- result.should eq([1,2,4,3])
21
- end
22
- end
23
-
@@ -1,58 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- require 'enumerable_to_scaruby'
4
-
5
- describe Enumerable do
6
- it 'has #count' do
7
- [1,2,3,4,5].count {|i| i > 2 }.should eq(3)
8
- end
9
- it 'has #diff' do
10
- [1,2,3].diff([2,3,4]).to_a.should eq([1])
11
- end
12
- it 'has #distinct' do
13
- [1,2,4,1,3,3,3,2,4,1].distinct.to_a.should eq([1,2,4,3])
14
- end
15
- it 'has #drop_right' do
16
- 1.upto(5).drop_right(3).to_a.should eq([1,2])
17
- end
18
- it 'has #drop_while' do
19
- [1,2,4,3,5].drop_while {|i| i < 3 }.to_a.should eq([4,3,5])
20
- end
21
- it 'has #ends_with' do
22
- 1.upto(5).ends_with([4,5]).should eq(true)
23
- end
24
- it 'has #exists' do
25
- 1.upto(5).exists {|i| i == 2 }.should eq(true)
26
- end
27
- it 'has #filter' do
28
- 1.upto(5).filter {|i| i < 3 }.to_a.should eq([1,2])
29
- end
30
- it 'has #filter_not' do
31
- 1.upto(5).filter_not {|i| i < 3 }.to_a.should eq([3,4,5])
32
- end
33
- it 'has #flat_map' do
34
- flatten = [[1,2],[3],[4,5]].flat_map {|i| i }.to_a
35
- flatten.should eq([1,2,3,4,5])
36
- end
37
- it 'has #flatten' do
38
- [[1,2,3],[4,5],[6]].flatten.to_a.should eq([1,2,3,4,5,6])
39
- end
40
- it 'has #fold_left' do
41
- 1.upto(5).fold_left(0) {|z,x| z + x }.should eq(15)
42
- end
43
- it 'has #forall' do
44
- 1.upto(5).forall {|i| i < 10 }.should eq(true)
45
- end
46
- it 'has #foreach' do
47
- 1.upto(5).foreach do |i|
48
- i.should <= 5
49
- end
50
- end
51
- it 'has #head' do
52
- 1.upto(5).head.should eq(1)
53
- end
54
- it 'has #head_option' do
55
- 1.upto(5).head_option.is_defined.should eq(true)
56
- end
57
- end
58
-