scaruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "rspec"
4
+
5
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,10 @@
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
+
@@ -0,0 +1,10 @@
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
+
@@ -0,0 +1,8 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Scaruby
4
+ class AppliableProc < Proc
5
+ alias_method :apply, :call
6
+ end
7
+ end
8
+
@@ -0,0 +1,126 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Scaruby
4
+ class Map
5
+
6
+ def self.empty
7
+ {}
8
+ end
9
+
10
+ def initialize(hash)
11
+ @hash = hash
12
+ end
13
+
14
+ def to_hash
15
+ @hash
16
+ end
17
+
18
+ def to_a
19
+ @hash.to_a
20
+ end
21
+
22
+ def contains(key)
23
+ @hash.include?(key)
24
+ end
25
+
26
+ def count(&predicate)
27
+ count = 0
28
+ @hash.each do |k,v|
29
+ if yield k, v then
30
+ count += 1
31
+ end
32
+ end
33
+ count
34
+ end
35
+
36
+ def exists(&predicate)
37
+ @hash.to_a.inject(false) {|found,kv|
38
+ if found then
39
+ true
40
+ else
41
+ k, v = kv[0], kv[1]
42
+ yield k, v
43
+ end
44
+ }
45
+ end
46
+
47
+ def filter(&predicate)
48
+ Map.new(@hash.reject {|k,v| ! yield k, v })
49
+ end
50
+
51
+ def filter_keys(&predicate)
52
+ Map.new(@hash.reject {|k,v| ! yield k })
53
+ end
54
+
55
+ def filter_not(&predicate)
56
+ Map.new(@hash.reject {|k,v| yield k, v })
57
+ end
58
+
59
+ def find(&predicate)
60
+ Option.new(@hash.inject([false,[]]) {|z,kv|
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,[]]
65
+ end
66
+ }[1])
67
+ end
68
+
69
+ def forall(&predicate)
70
+ @hash.inject(true) {|still_matched,kv|
71
+ if !still_matched then
72
+ false
73
+ else
74
+ k, v = kv[0], kv[1]
75
+ yield k, v
76
+ end
77
+ }
78
+ end
79
+
80
+ def foreach(&block)
81
+ @hash.each do |k,v| yield k, v end
82
+ end
83
+
84
+ def get_or_else(key, default_value)
85
+ value = @hash[key]
86
+ value.nil? ? default_value : value
87
+ end
88
+
89
+ def is_empty
90
+ @hash.nil? || @hash.empty?
91
+ end
92
+
93
+ def key_set
94
+ @hash.keys
95
+ end
96
+
97
+ def lift
98
+ AppliableProc.new {|k| Option.new(@hash[k]) }
99
+ end
100
+
101
+ def map(&block)
102
+ Map.new(Hash[*@hash.to_a.map {|k,v| yield k, v }.flatten])
103
+ end
104
+
105
+ def mk_string(*args)
106
+ case args.size
107
+ when 0
108
+ start_part, sep, end_part = '{', ', ', '}'
109
+ when 1
110
+ start_part, sep, end_part = '', args[0], ''
111
+ when 2
112
+ raise 'Illegal number of arguments'
113
+ else
114
+ start_part, sep, end_part = args[0], args[1], args[2]
115
+ end
116
+ #start_part + @hash.to_a.collect {|k,v| k.to_s + '=>' + v.to_s }.join(sep) + end_part
117
+ start_part + @hash.to_a.map {|k,v| k.to_s + '=>' + v.to_s }.join(sep) + end_part
118
+ end
119
+
120
+ def non_empty
121
+ ! is_empty
122
+ end
123
+
124
+ end
125
+ end
126
+
@@ -0,0 +1,6 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Scaruby
4
+ class NoSuchElementException < Exception
5
+ end
6
+ end
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby/no_such_element_exception'
4
+
5
+ module Scaruby
6
+ class Option
7
+
8
+ def self.apply(value)
9
+ Option.new(value)
10
+ end
11
+
12
+ def initialize(value)
13
+ @value = value
14
+ end
15
+
16
+ def is_defined
17
+ @value != nil
18
+ end
19
+
20
+ def get
21
+ if is_defined then @value
22
+ else raise NoSuchElementException
23
+ end
24
+ end
25
+
26
+ def get_or_else(default_value)
27
+ is_defined ? get : default_value
28
+ end
29
+
30
+ def map(&block)
31
+ is_defined ? Option.new(yield @value) : self
32
+ end
33
+
34
+ end
35
+ end
36
+
@@ -0,0 +1,338 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Scaruby
4
+ class Seq
5
+
6
+ def self.apply(enumerable)
7
+ Seq.new(enumerable)
8
+ end
9
+
10
+ def initialize(enumerable)
11
+ if enumerable.nil? || enumerable.is_a?(Enumerable) then
12
+ @array = enumerable.to_a
13
+ else
14
+ raise ArgumentError, 'Invalid argument (' + enumerable.to_s + ')'
15
+ end
16
+ end
17
+
18
+ def to_a
19
+ @array
20
+ end
21
+
22
+ def count(&predicate)
23
+ filter(&predicate).size
24
+ end
25
+
26
+ def diff(that)
27
+ filter {|e| ! that.include?(e) }
28
+ end
29
+
30
+ def distinct
31
+ Seq.new(@array.uniq)
32
+ end
33
+
34
+ def drop(n)
35
+ Seq.new(@array.drop(n))
36
+ end
37
+
38
+ def drop_right(n)
39
+ Seq.new(@array.reverse.drop(n).reverse)
40
+ end
41
+
42
+ def drop_while(&predicate)
43
+ Seq.new(@array.inject([false,[]]) {|passed,x|
44
+ 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)]
48
+ end
49
+ }[1])
50
+ end
51
+
52
+ def ends_with(that)
53
+ if that.nil? || that.length > @array.length then
54
+ return false
55
+ end
56
+ this_end = @array.reverse.take(that.length).reverse
57
+ 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]
61
+ end
62
+ }
63
+ end
64
+
65
+ def exists(&predicate)
66
+ @array.inject(false) {|found,e|
67
+ if found then true
68
+ else yield e
69
+ end
70
+ }
71
+ end
72
+
73
+ def filter(&predicate)
74
+ Seq.new(@array.select {|e| yield e })
75
+ end
76
+
77
+ def filter_not(&predicate)
78
+ Seq.new(@array.select {|e| ! yield e })
79
+ end
80
+
81
+ def find(&predicate)
82
+ Option.new(@array.find(&predicate))
83
+ end
84
+
85
+ def flat_map(&block)
86
+ Seq.new(@array.inject([]) {|z,x|
87
+ applied = yield x
88
+ if applied.is_a?(Enumerable) then
89
+ applied.inject(z) {|z,elm| z.push(elm) }
90
+ elsif applied.is_a?(Option) then
91
+ applied.is_defined ? z.push(applied.get) : z
92
+ else z.push(applied)
93
+ end
94
+ })
95
+ end
96
+
97
+ def flatten
98
+ Seq.new(@array.inject([]) {|z,x|
99
+ if x.is_a?(Enumerable) then
100
+ x.inject(z) {|z,elm| z.push(elm) }
101
+ elsif x.is_a?(Option) then
102
+ x.is_defined ? z.push(x.get) : z
103
+ else
104
+ z.push(x)
105
+ end
106
+ })
107
+ end
108
+
109
+ def fold_left(z, &block)
110
+ @array.inject(z) {|z,x| yield z, x }
111
+ end
112
+
113
+ def forall(&predicate)
114
+ @array.inject(true) {|all_matched,e|
115
+ if ! all_matched then false
116
+ else yield e
117
+ end
118
+ }
119
+ end
120
+
121
+ def foreach(&block)
122
+ @array.each do |e| yield e end
123
+ end
124
+
125
+ def head
126
+ @array.first
127
+ end
128
+
129
+ def head_option
130
+ Option.new(@array.first)
131
+ end
132
+
133
+ def indices
134
+ Seq.new(0.upto @array.length-1)
135
+ end
136
+
137
+ def init
138
+ Seq.new(@array.take(@array.length - 1))
139
+ end
140
+
141
+ def intersect(that)
142
+ Seq.new(@array.inject([]) {|z,x|
143
+ that.include?(x) ? z.push(x) : z
144
+ })
145
+ end
146
+
147
+ def is_empty
148
+ @array.nil? || @array.empty?
149
+ end
150
+
151
+ def last
152
+ @array.last
153
+ end
154
+
155
+ def last_option
156
+ Option.new(@array.last)
157
+ end
158
+
159
+ def length
160
+ @array.length
161
+ end
162
+
163
+ def lift
164
+ AppliableProc.new {|i| Option.new(@array[i]) }
165
+ end
166
+
167
+ def map(&block)
168
+ #Seq.new(@array.collect {|e| yield e })
169
+ Seq.new(@array.map {|e| yield e })
170
+ end
171
+
172
+ def max
173
+ @array.max
174
+ end
175
+
176
+ def min
177
+ @array.min
178
+ end
179
+
180
+ def mk_string(*args)
181
+ case args.length
182
+ when 0
183
+ start_part, sep, end_part = '', '', ''
184
+ when 1
185
+ start_part, sep, end_part = '', args[0], ''
186
+ when 2
187
+ raise ArgumentError, 'Illegal number of arguments (' + args.length.to_s + ')'
188
+ else
189
+ start_part, sep, end_part = args[0], args[1], args[2]
190
+ end
191
+ start_part + @array.join(sep) + end_part
192
+ end
193
+
194
+ def non_empty
195
+ ! is_empty
196
+ end
197
+
198
+ def partition(&predicate)
199
+ 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)]
202
+ end
203
+ })
204
+ end
205
+
206
+ def patch(from, patch, replaced)
207
+ Seq.new(
208
+ @array.take(from)
209
+ .concat(patch)
210
+ .concat(@array.drop(from).drop(replaced)))
211
+ end
212
+
213
+ def reverse
214
+ Seq.new(@array.reverse)
215
+ end
216
+
217
+ def reverse_map(&block)
218
+ #Seq.new(@array.reverse.collect {|e| yield e })
219
+ Seq.new(@array.reverse.map {|e| yield e })
220
+ end
221
+
222
+ def same_elements(that)
223
+ @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]
227
+ end
228
+ }
229
+ end
230
+
231
+ def scan_left(n, &block)
232
+ Seq.new(@array.inject([n,[n]]) {|last_and_array,x|
233
+ last, array = last_and_array[0], last_and_array[1]
234
+ applied = yield last, x
235
+ [applied, array.push(applied)]
236
+ }[1])
237
+ end
238
+
239
+ def scan_right(n, &block)
240
+ Seq.new(@array.reverse.inject([n,[n]]) {|last_and_array,x|
241
+ last, array = last_and_array[0], last_and_array[1]
242
+ applied = yield last, x
243
+ [applied, array.push(applied)]
244
+ }[1].reverse)
245
+ end
246
+
247
+ def size
248
+ @array.length
249
+ end
250
+
251
+ def slice(from, until_n)
252
+ Seq.new(@array.drop(from).take(until_n - from))
253
+ end
254
+
255
+ def sliding(len)
256
+ result = []
257
+ @array.each_with_index do |e,idx|
258
+ if idx < (@array.length - len + 1) then
259
+ result.push(@array.slice(idx, len))
260
+ end
261
+ end
262
+ Seq.new(result)
263
+ end
264
+
265
+ def sort_with(&predicate)
266
+ @array.sort(&predicate)
267
+ end
268
+
269
+ def span(&predicate)
270
+ result = @array.inject([true,[],[]]) {|z,x|
271
+ 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)]
275
+ end
276
+ }
277
+ Seq.new([result[1],result[2]])
278
+ end
279
+
280
+ def split_at(n)
281
+ Seq.new([@array.take(n),@array.drop(n)])
282
+ end
283
+
284
+ def starts_with(that)
285
+ if that.nil? || that.length > @array.length then
286
+ return false
287
+ end
288
+ this_start = @array.take(that.length)
289
+ 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]
293
+ end
294
+ }
295
+ end
296
+
297
+ def sum
298
+ @array.inject(0) {|z,x| z + x }
299
+ end
300
+
301
+ def tail
302
+ Seq.new(@array.drop(1))
303
+ end
304
+
305
+ def take(n)
306
+ Seq.new(@array.take(n))
307
+ end
308
+
309
+ def take_right(n)
310
+ Seq.new(@array.reverse.take(n).reverse)
311
+ end
312
+
313
+ def take_while(&predicate)
314
+ Seq.new(@array.inject([false,[]]) {|passed,x|
315
+ 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]
319
+ end
320
+ }[1])
321
+ end
322
+
323
+ def union(that)
324
+ Seq.new(@array.concat(that))
325
+ end
326
+
327
+ def zip(that)
328
+ Seq.new(@array.zip(that).select {|a,b| ! a.nil? && ! b.nil? })
329
+ end
330
+
331
+ def zip_with_index
332
+ with_index = []
333
+ @array.each_with_index do |v,idx| with_index.push([v,idx]) end
334
+ with_index
335
+ end
336
+
337
+ end
338
+ end
@@ -0,0 +1,6 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Scaruby
4
+ VERSION = "0.0.1"
5
+ end
6
+
data/lib/scaruby.rb ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby/appliable_proc'
4
+ require 'scaruby/map'
5
+ require 'scaruby/no_such_element_exception'
6
+ require 'scaruby/option'
7
+ require 'scaruby/seq'
8
+ require 'scaruby/version'
9
+
10
+ module Scaruby
11
+ end
12
+
13
+ # alias
14
+ class AppliableProc < Scaruby::AppliableProc
15
+ end
16
+ class Map < Scaruby::Map
17
+ end
18
+ class Option < Scaruby::Option
19
+ end
20
+ class Seq < Scaruby::Seq
21
+ end
22
+
data/readme.md ADDED
@@ -0,0 +1,53 @@
1
+ # Ruby reference for Scala programmers
2
+
3
+ Surely it works fine. But it mainly serves as a Ruby reference for Scala programmers.
4
+
5
+ ## Setup
6
+
7
+ ```sh
8
+ git clone git://github.com/seratch/scaruby.git
9
+ cd scaruby
10
+ gem install bundler
11
+ bundle install
12
+ ```
13
+
14
+ ## Trying on irb
15
+
16
+ ```sh
17
+ bundle console
18
+ ```
19
+
20
+ ```ruby
21
+ irb(main):001:0> require 'scaruby'
22
+ => false
23
+
24
+ irb(main):003:0> Option.new(nil).is_defined
25
+ => false
26
+ irb(main):004:0> Option.new(123).is_defined
27
+ => true
28
+
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
35
+ => [1]
36
+
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]
39
+
40
+ irb(main):003:0> Seq.new([1,2,3]).fold_left(0) {|z,x| z + x }
41
+ => 6
42
+
43
+ irb(main):001:0> require 'enumerable_to_scaruby'
44
+ => true
45
+ irb(main):002:0> [[1,2,3],[4,5],[6]].flat_map {|e| e }
46
+ => [1, 2, 3, 4, 5, 6]
47
+ ```
48
+
49
+ ## Testing
50
+
51
+ ```sh
52
+ bundle exec rspec
53
+ ```
data/scaruby.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "scaruby/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "scaruby"
7
+ s.version = Scaruby::VERSION
8
+ s.authors = ["Kazuhiro Sera"]
9
+ s.email = ["seratch@gmail.com"]
10
+ s.homepage = "https://github.com/seratch/scaruby"
11
+ s.summary = %q{Scala API in Ruby}
12
+ s.description = %q{Scala API in Ruby}
13
+
14
+ s.rubyforge_project = "scaruby"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
@@ -0,0 +1,23 @@
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
+
@@ -0,0 +1,58 @@
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
+
@@ -0,0 +1,81 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby'
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 self.new' do
10
+ map = Map.new({1 => 'a', 2 => 'b'})
11
+ map.should_not eq(nil)
12
+ end
13
+ it 'has #contains' do
14
+ Map.new(hash).contains(123).should eq(true)
15
+ Map.new(hash).contains(999).should eq(false)
16
+ end
17
+ it 'has #count' do
18
+ Map.new(hash).count {|k,v| k.to_s.length >= 2 }.should eq(5)
19
+ end
20
+ it 'hash Map.empty' do
21
+ Map.empty.should eq({})
22
+ end
23
+ it 'has #exists' do
24
+ Map.new(hash).exists {|k,v| k.to_s.length == 1 }.should eq(true)
25
+ end
26
+ it 'has #filter' do
27
+ Map.new(hash).filter {|k,v| k.to_s.length < 3 }.to_hash.size.should eq(4)
28
+ end
29
+ it 'has #filter_keys' do
30
+ Map.new(hash).filter_keys {|k| k.to_s.length < 3 }.to_hash.size.should eq(4)
31
+ end
32
+ it 'has #filter_not' do
33
+ Map.new(hash).filter_not {|k| k.to_s.length < 3 }.to_hash.to_s.should eq('{123=>"abc", 234=>"bcd", 345=>"cde"}')
34
+ end
35
+ it 'has #find' do
36
+ Map.new(hash).find {|k,v| k.to_s.length == 2 }.get[1].should eq('ef')
37
+ end
38
+ it 'has #forall' do
39
+ Map.new(hash).forall {|k,v| k.to_s.length <= 3 }.should eq(true)
40
+ Map.new(hash).forall {|k,v| k.to_s.length >= 2 }.should eq(false)
41
+ end
42
+ it 'has #foreach' do
43
+ Map.new(hash).foreach do |k,v|
44
+ hash.include?(k).should eq(true)
45
+ end
46
+ end
47
+ it 'has #get_or_else' do
48
+ Map.new(hash).get_or_else(123, 'xxx').should eq('abc')
49
+ Map.new(hash).get_or_else(999, 'xxx').should eq('xxx')
50
+ end
51
+ it 'has #is_empty' do
52
+ Map.new(hash).is_empty.should eq(false)
53
+ Map.new({}).is_empty.should eq(true)
54
+ Map.new(nil).is_empty.should eq(true)
55
+ end
56
+ it 'has #key_set' do
57
+ Map.new(hash).key_set.should eq(hash.keys)
58
+ end
59
+ it 'has #lift' do
60
+ lifted = Map.new(hash).lift
61
+ lifted.apply(123).get.should eq('abc')
62
+ lifted.apply(999).is_defined.should eq(false)
63
+ lifted.call(123).get.should eq('abc')
64
+ lifted.call(999).is_defined.should eq(false)
65
+ end
66
+ it 'has #map' do
67
+ new_map = Map.new(hash).map {|k,v| [k+k,v] }.to_hash
68
+ new_map.include?(246).should eq(true)
69
+ end
70
+ it 'has #mk_string' do
71
+ Map.new(hash).mk_string().should eq('{123=>abc, 234=>bcd, 345=>cde, 4=>d, 56=>ef, 7=>g, 89=>hi}')
72
+ end
73
+ it 'has #non_empty' do
74
+ Map.new(hash).non_empty.should eq(true)
75
+ Map.new({}).non_empty.should eq(false)
76
+ Map.new(nil).non_empty.should eq(false)
77
+ end
78
+ end
79
+
80
+
81
+
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby'
4
+
5
+ describe Option do
6
+ it 'has self.new' do
7
+ some = Option.new(123)
8
+ some.is_defined.should eq(true)
9
+ end
10
+ it 'has #get and it works with Some' do
11
+ some = Option.new(123)
12
+ some.get.should eq(123)
13
+ end
14
+ it 'has #get and it works with None' do
15
+ none = Option.new(nil)
16
+ begin
17
+ none.get
18
+ violated "NoSuchElementException should be thorwn!"
19
+ rescue Scaruby::NoSuchElementException => e
20
+ end
21
+ end
22
+ it 'has #get_or_else and it works with Some' do
23
+ some = Option.new(123)
24
+ some.get_or_else(999).should eq(123)
25
+ end
26
+ it 'has #get_or_else and it works with None' do
27
+ none = Option.new(nil)
28
+ none.get_or_else(999).should eq(999)
29
+ end
30
+ it 'has #map and it works with Some' do
31
+ some = Option.new(123)
32
+ some_result = some.map {|v| v + v }
33
+ some_result.get_or_else(999).should eq(246)
34
+ end
35
+ it 'has #map and it works with None' do
36
+ none = Option.new(nil)
37
+ none_result = none.map {|v| v + v }
38
+ none_result.get_or_else(999).should eq(999)
39
+ end
40
+ end
41
+
42
+
43
+
@@ -0,0 +1,263 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'scaruby'
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 'does not accept invalid args' do
11
+ begin
12
+ Seq.new('aaaa').should eq(nil)
13
+ rescue ArgumentError
14
+ end
15
+ begin
16
+ Seq.new(12345).should eq(nil)
17
+ rescue ArgumentError
18
+ end
19
+ end
20
+ it 'has #to_a' do
21
+ Seq.new(one_to_five).to_a.should eq([1,2,3,4,5])
22
+ end
23
+ it 'has #count' do
24
+ Seq.new(one_to_five).count {|i| i > 2 }.should eq(3)
25
+ end
26
+ it 'has #diff' do
27
+ Seq.new([1,2,3]).diff([2,3,4]).to_a.should eq([1])
28
+ end
29
+ it 'has #distinct' do
30
+ Seq.new([1,2,4,1,3,3,3,2,4,1]).distinct.to_a.should eq([1,2,4,3])
31
+ end
32
+ it 'has #drop' do
33
+ Seq.new(one_to_five).drop(3).to_a.should eq([4,5])
34
+ Seq.new(one_to_five).drop(7).to_a.should eq([])
35
+ end
36
+ it 'has #drop_right' do
37
+ Seq.new(one_to_five).drop_right(3).to_a.should eq([1,2])
38
+ Seq.new(one_to_five).drop_right(7).to_a.should eq([])
39
+ end
40
+ it 'has #drop_while' do
41
+ Seq.new([5,3,2,4,1]).drop_while {|e| e > 2 }.to_a.should eq([2,4,1])
42
+ end
43
+ it 'has #ends_with' do
44
+ Seq.new([1,2,3]).ends_with([1,2]).should eq(false)
45
+ Seq.new([1,2,3]).ends_with([1,2,3]).should eq(true)
46
+ Seq.new([1,2,3]).ends_with([1,1,2,3]).should eq(false)
47
+ Seq.new([1,2,3]).ends_with([2,3]).should eq(true)
48
+ Seq.new([1,2,3]).ends_with([3]).should eq(true)
49
+ end
50
+ it 'has #exists' do
51
+ Seq.new([1,2,3]).exists {|i| i < 2 }.should eq(true)
52
+ Seq.new([1,2,3]).exists {|i| i < 4 }.should eq(true)
53
+ Seq.new([2,3,4]).exists {|i| i > 4 }.should eq(false)
54
+ end
55
+ it 'has #filter' do
56
+ Seq.new(one_to_five).filter {|i| i > 3 }.to_a.should eq([4,5])
57
+ Seq.new(one_to_five).filter {|i| i > 10 }.to_a.should eq([])
58
+ end
59
+ it 'has #filter_not' do
60
+ Seq.new(one_to_five).filter_not {|i| i > 3 }.to_a.should eq([1,2,3])
61
+ Seq.new(one_to_five).filter_not {|i| i > 10 }.to_a.should eq([1,2,3,4,5])
62
+ end
63
+ it 'has #find' do
64
+ some = Seq.new(one_to_five).find {|i| i < 3 }
65
+ some.get.should eq(1)
66
+ some = Seq.new(one_to_five).find {|i| i > 10 }
67
+ some.is_defined.should eq(false)
68
+ end
69
+ it 'has #flat_map and it works with nested arrays' do
70
+ Seq.new([[1,2],[3,4],[5]]).flat_map {|i| i }.to_a.should eq([1,2,3,4,5])
71
+ end
72
+ it 'has #flat_map and it works with Option elements' do
73
+ Seq.new([1,2,nil,3]).flat_map {|i| Option.new(i) }.to_a.should eq([1,2,3])
74
+ end
75
+ it 'has #fold_left' do
76
+ Seq.new(one_to_five_shuffled).fold_left(0) {|z,x| z + x }.should eq(15)
77
+ end
78
+ it 'has #flatten' do
79
+ Seq.new([[1,2],[3,4],[5]]).flatten.to_a.should eq([1,2,3,4,5])
80
+ Seq.new(
81
+ [Option.new(1),
82
+ Option.new(2),
83
+ Option.new(nil),
84
+ Option.new(3)]
85
+ ).flatten.to_a.should eq([1,2,3])
86
+ end
87
+ it 'has #forall' do
88
+ Seq.new([1,2,3]).forall {|i| i > 0 }.should eq(true)
89
+ Seq.new([1,2,3]).forall {|i| i > 1 }.should eq(false)
90
+ end
91
+ it 'has #foreach' do
92
+ count = 0
93
+ Seq.new([1,2,3]).foreach do |i|
94
+ count += 1
95
+ end
96
+ count.should eq(3)
97
+ end
98
+ it 'has #head' do
99
+ Seq.new(one_to_five).head.should eq(1)
100
+ end
101
+ it 'has #head_option and it works with Some' do
102
+ some = Seq.new(one_to_five).head_option
103
+ some.get_or_else(999).should eq(1)
104
+ end
105
+ it 'has #head_option and it works with None' do
106
+ none = Seq.new([]).head_option
107
+ none.get_or_else(999).should eq(999)
108
+ end
109
+ it 'has #indices' do
110
+ Seq.new([1,2,3]).indices.to_a.should eq([0,1,2])
111
+ end
112
+ it 'has #init' do
113
+ Seq.new([1,2,3]).init.to_a.should eq([1,2])
114
+ end
115
+ it 'has #intersect' do
116
+ Seq.new([1,2,3]).intersect([2,3,4]).to_a.should eq([2,3])
117
+ end
118
+ it 'has #is_empty' do
119
+ Seq.new([1,2,3]).is_empty.should eq(false)
120
+ Seq.new([nil]).is_empty.should eq(false)
121
+ Seq.new([]).is_empty.should eq(true)
122
+ Seq.new(nil).is_empty.should eq(true)
123
+ end
124
+ it 'has #last' do
125
+ Seq.new([1,2,3]).last.should eq(3)
126
+ end
127
+ it 'has #last_option' do
128
+ some = Seq.new([1,2,3]).last_option
129
+ some.get.should eq(3)
130
+ none = Seq.new([]).last_option
131
+ none.is_defined.should eq(false)
132
+ end
133
+ it 'has #lift' do
134
+ seq_lift = Seq.new([1,2,3]).lift
135
+ seq_lift.apply(0).get.should eq(1)
136
+ seq_lift.apply(1).get.should eq(2)
137
+ seq_lift.apply(2).get.should eq(3)
138
+ seq_lift.apply(3).is_defined.should eq(false)
139
+ seq_lift.call(0).get.should eq(1)
140
+ seq_lift.call(1).get.should eq(2)
141
+ seq_lift.call(2).get.should eq(3)
142
+ seq_lift.call(3).is_defined.should eq(false)
143
+ end
144
+ it 'has #map' do
145
+ Seq.new([1,2,3]).map {|i| i + i }.to_a.should eq([2,4,6])
146
+ end
147
+ it 'has #max' do
148
+ Seq.new(one_to_five_shuffled).max.should eq(5)
149
+ end
150
+ it 'has #min' do
151
+ Seq.new(one_to_five_shuffled).min.should eq(1)
152
+ end
153
+ it 'has #mk_string' do
154
+ Seq.new(one_to_five).mk_string.should eq('12345')
155
+ Seq.new(one_to_five).mk_string(',').should eq('1,2,3,4,5')
156
+ Seq.new(one_to_five).mk_string('^',',','$').should eq('^1,2,3,4,5$')
157
+ begin
158
+ Seq.new(one_to_five).mk_string('a','b').should eq(nil)
159
+ rescue ArgumentError
160
+ end
161
+ Seq.new(one_to_five).mk_string('^',',','$','zzz').should eq('^1,2,3,4,5$')
162
+ end
163
+ it 'has #non_empty' do
164
+ Seq.new(one_to_five).non_empty.should eq(true)
165
+ Seq.new([]).non_empty.should eq(false)
166
+ Seq.new(nil).non_empty.should eq(false)
167
+ end
168
+ it 'has #partition' do
169
+ Seq.new([5,2,3,1,4,2,3]).partition {|i| i < 3 }.to_a.should eq([[2,1,2],[5,3,4,3]])
170
+ end
171
+ it 'has #patch' do
172
+ 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
+ end
174
+ it 'has #reduce_left' do
175
+ end
176
+ it 'has #reduce_right' do
177
+ end
178
+ it 'has #reverse' do
179
+ Seq.new([1,2,3]).reverse.to_a.should eq([3,2,1])
180
+ end
181
+ it 'has #reverse_iterator' do
182
+ end
183
+ it 'has #reverse_map' do
184
+ Seq.new([1,2,3]).reverse_map {|i| i + i }.to_a.should eq([6,4,2])
185
+ end
186
+ it 'has #same_elements' do
187
+ Seq.new([1,2,3]).same_elements([1,2,3]).should eq(true)
188
+ Seq.new([1,2,3]).same_elements([1,3,2]).should eq(false)
189
+ Seq.new([1,2,3]).same_elements([1,2]).should eq(false)
190
+ end
191
+ it 'has #scan_left' do
192
+ Seq.new([1,2,3]).scan_left(1) {|a,b| a + b }.to_a.should eq([1,2,4,7])
193
+ end
194
+ it 'has #scan_right' do
195
+ Seq.new([1,2,3]).scan_right(1) {|a,b| a + b }.to_a.should eq([7,6,4,1])
196
+ end
197
+ it 'has #slice' do
198
+ Seq.new([1,2,3,4,5]).slice(1,1).to_a.should eq([])
199
+ Seq.new([1,2,3,4,5]).slice(1,2).to_a.should eq([2])
200
+ Seq.new([1,2,3,4,5]).slice(1,3).to_a.should eq([2,3])
201
+ Seq.new([1,2,3,4,5]).slice(1,4).to_a.should eq([2,3,4])
202
+ end
203
+ it 'has #sliding' do
204
+ Seq.new([1,2,3,4,5]).sliding(2).to_a.should eq([[1,2],[2,3],[3,4],[4,5]])
205
+ end
206
+ it 'has #sort_with' do
207
+ Seq.new([1,3,2,4,5]).sort_with {|a,b| b <=> a }.to_a.should eq([5,4,3,2,1])
208
+ end
209
+ it 'has #span' do
210
+ Seq.new([1,2,3,2,1]).span {|i| i < 3 }.to_a.should eq([[1,2],[3,2,1]])
211
+ end
212
+ it 'has #split_at' do
213
+ Seq.new([1,2,3,2,1]).split_at(3).to_a.should eq([[1,2,3],[2,1]])
214
+ end
215
+ it 'has #starts_with' do
216
+ Seq.new([1,2,3]).starts_with([1]).should eq(true)
217
+ Seq.new([1,2,3]).starts_with([1,2]).should eq(true)
218
+ Seq.new([1,2,3]).starts_with([1,2,3]).should eq(true)
219
+ Seq.new([1,2,3]).starts_with([1,2,3,4]).should eq(false)
220
+ Seq.new([1,2,3]).starts_with([2,3]).should eq(false)
221
+ Seq.new([1,2,3]).starts_with([4,1,2,3]).should eq(false)
222
+ end
223
+ it 'has #sum' do
224
+ Seq.new([1,2,3]).sum.should eq(6)
225
+ end
226
+ it 'has #tail' do
227
+ Seq.new([1,2,3]).tail.to_a.should eq([2,3])
228
+ Seq.new([]).tail.to_a.should eq([])
229
+ end
230
+ it 'has #take' do
231
+ Seq.new([1,2,3]).take(0).to_a.should eq([])
232
+ Seq.new([1,2,3]).take(1).to_a.should eq([1])
233
+ Seq.new([1,2,3]).take(2).to_a.should eq([1,2])
234
+ Seq.new([1,2,3]).take(3).to_a.should eq([1,2,3])
235
+ Seq.new([1,2,3]).take(4).to_a.should eq([1,2,3])
236
+ end
237
+ it 'has #take_right' do
238
+ Seq.new([1,2,3]).take_right(0).to_a.should eq([])
239
+ Seq.new([1,2,3]).take_right(1).to_a.should eq([3])
240
+ Seq.new([1,2,3]).take_right(2).to_a.should eq([2,3])
241
+ Seq.new([1,2,3]).take_right(3).to_a.should eq([1,2,3])
242
+ Seq.new([1,2,3]).take_right(4).to_a.should eq([1,2,3])
243
+ end
244
+ it 'has #take_while' do
245
+ Seq.new([5,3,2,4,1]).take_while {|e| e > 2 }.to_a.should eq([5,3])
246
+ end
247
+ it 'has #union' do
248
+ Seq.new([1,2,3]).union([2,3,4]).to_a.should eq([1,2,3,2,3,4])
249
+ end
250
+ it 'has #zip' do
251
+ Seq.new([1,2,3]).zip([2,3]).to_a.should eq([[1,2],[2,3]])
252
+ Seq.new([1,2,3]).zip([2,3,4]).to_a.should eq([[1,2],[2,3],[3,4]])
253
+ Seq.new([1,2,3]).zip([2,3,4,5]).to_a.should eq([[1,2],[2,3],[3,4]])
254
+ end
255
+ it 'has #zip_with_index' do
256
+ Seq.new([]).zip_with_index.to_a.should eq([])
257
+ Seq.new([1,2,3]).zip_with_index.to_a.should eq([[1,0],[2,1],[3,2]])
258
+ end
259
+ end
260
+
261
+
262
+
263
+
@@ -0,0 +1,7 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ describe Scaruby do
4
+ it 'is available' do
5
+ end
6
+ end
7
+
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scaruby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Kazuhiro Sera
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-03-02 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: Scala API in Ruby
17
+ email:
18
+ - seratch@gmail.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - .gitignore
27
+ - Gemfile
28
+ - Rakefile
29
+ - lib/array_to_scaruby.rb
30
+ - lib/enumerable_to_scaruby.rb
31
+ - lib/scaruby.rb
32
+ - lib/scaruby/appliable_proc.rb
33
+ - lib/scaruby/map.rb
34
+ - lib/scaruby/no_such_element_exception.rb
35
+ - lib/scaruby/option.rb
36
+ - lib/scaruby/seq.rb
37
+ - lib/scaruby/version.rb
38
+ - readme.md
39
+ - scaruby.gemspec
40
+ - spec/array_to_scaruby_spec.rb
41
+ - spec/enumerable_to_scaruby_spec.rb
42
+ - spec/scaruby/map_spec.rb
43
+ - spec/scaruby/option_spec.rb
44
+ - spec/scaruby/seq_spec.rb
45
+ - spec/scaruby_spec.rb
46
+ homepage: https://github.com/seratch/scaruby
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ requirements: []
67
+
68
+ rubyforge_project: scaruby
69
+ rubygems_version: 1.8.15
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Scala API in Ruby
73
+ test_files:
74
+ - spec/array_to_scaruby_spec.rb
75
+ - spec/enumerable_to_scaruby_spec.rb
76
+ - spec/scaruby/map_spec.rb
77
+ - spec/scaruby/option_spec.rb
78
+ - spec/scaruby/seq_spec.rb
79
+ - spec/scaruby_spec.rb