scaruby 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
-