jruby-scala-collections 0.1.0
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/README.md +24 -0
- data/ext/dist/collections.jar +0 -0
- data/lib/jruby/scala_support.rb +365 -0
- metadata +48 -0
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
## What is it?
|
2
|
+
|
3
|
+
A tiny interoperability library for passing JRuby/Scala collections back
|
4
|
+
and forth.
|
5
|
+
|
6
|
+
## How do you use it?
|
7
|
+
|
8
|
+
Each ```Object``` has two methods: ```#to_scala``` and ```#from_scala```.
|
9
|
+
These can be used to wrap JRuby/Scala collections.
|
10
|
+
|
11
|
+
Example:
|
12
|
+
|
13
|
+
gem 'jruby-scala-collections'
|
14
|
+
require 'jruby/scala_support'
|
15
|
+
|
16
|
+
r_arr = [1,2,3,4]
|
17
|
+
scala_arr = scala_object.do_stuff(r_arr.to_scala)
|
18
|
+
scala_arr.from_scala
|
19
|
+
|
20
|
+
## Disclaimer
|
21
|
+
|
22
|
+
This library was written by Artūras 'arturaz' Šlajus for personal
|
23
|
+
usage. ```#to_scala``` should work pretty well, however Ruby wrappers
|
24
|
+
may be missing methods. Patches are welcome.
|
Binary file
|
@@ -0,0 +1,365 @@
|
|
1
|
+
require 'jruby'
|
2
|
+
require File.dirname(__FILE__) + '/../../ext/dist/collections.jar'
|
3
|
+
|
4
|
+
module JRuby::ScalaSupport
|
5
|
+
class ImmutableException < StandardError; end
|
6
|
+
|
7
|
+
module Common
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
# Fake _target_ identity. This extends #is_a?, #kind_of?, #instance_of? on
|
11
|
+
# _target_ and #=== on _pretended_klass_.
|
12
|
+
#
|
13
|
+
# Example: fake_identity YourCustomHash, Hash
|
14
|
+
#
|
15
|
+
# Beware that #<, #<= and #ancestors on _target_ will still return that
|
16
|
+
# _target_ is not _pretended_klass_.
|
17
|
+
#
|
18
|
+
# @param [Class] target class that is being given fake identity
|
19
|
+
# @param [Class] pretended_klass class that target is pretending to be
|
20
|
+
def self.fake_identity(target, pretended_klass)
|
21
|
+
target.instance_eval do
|
22
|
+
[:is_a?, :kind_of?, :instance_of?].each do |method|
|
23
|
+
define_method(method) do |klass|
|
24
|
+
klass == pretended_klass ? true : super(klass)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
(class << pretended_klass; self; end).instance_eval do
|
30
|
+
define_method(:===) do |object|
|
31
|
+
if object.is_a?(target)
|
32
|
+
true
|
33
|
+
else
|
34
|
+
super(object)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(raw)
|
41
|
+
@raw = raw
|
42
|
+
end
|
43
|
+
|
44
|
+
def scala_collection
|
45
|
+
@raw
|
46
|
+
end
|
47
|
+
|
48
|
+
def blank?
|
49
|
+
@raw.isEmpty
|
50
|
+
end
|
51
|
+
|
52
|
+
def size
|
53
|
+
@raw.size
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module Map
|
58
|
+
module Common
|
59
|
+
include JRuby::ScalaSupport::Common
|
60
|
+
|
61
|
+
def [](key)
|
62
|
+
value = @raw.get(key)
|
63
|
+
if value == None
|
64
|
+
nil
|
65
|
+
else
|
66
|
+
value.get.from_scala
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def has_key?(key)
|
71
|
+
@raw.contains(key)
|
72
|
+
end
|
73
|
+
|
74
|
+
def each
|
75
|
+
if block_given?
|
76
|
+
@raw.foreach do |tuple|
|
77
|
+
yield tuple._1.from_scala, tuple._2.from_scala
|
78
|
+
end
|
79
|
+
else
|
80
|
+
iterator = @raw.iterator
|
81
|
+
|
82
|
+
Enumerator.new do |yielder|
|
83
|
+
while iterator.hasNext
|
84
|
+
tuple = iterator.next
|
85
|
+
yielder << [tuple._1.from_scala, tuple._2.from_scala]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_s
|
92
|
+
first = true
|
93
|
+
each_with_object("{") do |(key, value), str|
|
94
|
+
first ? first = false : str << ", "
|
95
|
+
str << "#{key}=>#{value}"
|
96
|
+
end << "}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def as_json(options=nil)
|
100
|
+
each_with_object({}) do |(key, value), hash|
|
101
|
+
hash[key.as_json(options)] = value.as_json(options)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class Immutable
|
107
|
+
include Common
|
108
|
+
JRuby::ScalaSupport::Common.fake_identity self, Hash
|
109
|
+
|
110
|
+
def []=(key, value)
|
111
|
+
raise ImmutableException,
|
112
|
+
"Cannot change #{key} on #{self} because it is immutable!"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class Mutable
|
117
|
+
include Common
|
118
|
+
JRuby::ScalaSupport::Common.fake_identity self, Hash
|
119
|
+
|
120
|
+
def []=(key, value)
|
121
|
+
@raw.update(key, value.to_scala)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
module Seq
|
127
|
+
module Common
|
128
|
+
include JRuby::ScalaSupport::Common
|
129
|
+
|
130
|
+
def [](index)
|
131
|
+
if index < 0
|
132
|
+
@raw.apply(size + index).from_scala
|
133
|
+
elsif index >= size
|
134
|
+
nil
|
135
|
+
else
|
136
|
+
@raw.apply(index).from_scala
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def each
|
141
|
+
if block_given?
|
142
|
+
@raw.foreach do |item|
|
143
|
+
yield item.from_scala
|
144
|
+
end
|
145
|
+
else
|
146
|
+
iterator = @raw.iterator
|
147
|
+
|
148
|
+
Enumerator.new do |yielder|
|
149
|
+
yielder << iterator.next.from_scala while iterator.hasNext
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def to_s
|
155
|
+
first = true
|
156
|
+
each_with_object("[") do |item, str|
|
157
|
+
first ? first = false : str << ", "
|
158
|
+
str << item.to_s
|
159
|
+
end << "]"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class Immutable
|
164
|
+
include Common
|
165
|
+
JRuby::ScalaSupport::Common.fake_identity self, Array
|
166
|
+
|
167
|
+
def []=(index, value)
|
168
|
+
raise ImmutableException,
|
169
|
+
"Cannot assign #{value} to index #{index} on #{self
|
170
|
+
}: collection immutable"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
class Mutable
|
175
|
+
include Common
|
176
|
+
JRuby::ScalaSupport::Common.fake_identity self, Array
|
177
|
+
|
178
|
+
def []=(index, value)
|
179
|
+
if index < 0
|
180
|
+
@raw.update(size + index, value.to_scala)
|
181
|
+
elsif index >= size
|
182
|
+
(index - size + 1).times { @raw.send(:"+=", nil) }
|
183
|
+
self[index] = value
|
184
|
+
else
|
185
|
+
@raw.update(index, value.to_scala)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
module Set
|
192
|
+
module Common
|
193
|
+
include JRuby::ScalaSupport::Common
|
194
|
+
|
195
|
+
def +(o)
|
196
|
+
(@raw + o).from_scala
|
197
|
+
end
|
198
|
+
|
199
|
+
def -(o)
|
200
|
+
(@raw - o).from_scala
|
201
|
+
end
|
202
|
+
|
203
|
+
def each
|
204
|
+
if block_given?
|
205
|
+
@raw.foreach { |item| yield item.from_scala }
|
206
|
+
else
|
207
|
+
Enumerator.new do |yielder|
|
208
|
+
each { |item| yielder << item }
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def to_s
|
214
|
+
first = true
|
215
|
+
each_with_object("#<Set: {") do |item, str|
|
216
|
+
first ? first = false : str << ", "
|
217
|
+
str << item.to_s
|
218
|
+
end << "}>"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
class Immutable
|
223
|
+
include Common
|
224
|
+
JRuby::ScalaSupport::Common.fake_identity self, Set
|
225
|
+
|
226
|
+
def add(o)
|
227
|
+
raise ImmutableException,
|
228
|
+
"Cannot add #{o} to #{self}: immutable collection"
|
229
|
+
end
|
230
|
+
|
231
|
+
def delete(o)
|
232
|
+
raise ImmutableException,
|
233
|
+
"Cannot delete #{o} from #{self}: immutable collection"
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
class Mutable
|
238
|
+
include Common
|
239
|
+
JRuby::ScalaSupport::Common.fake_identity self, Set
|
240
|
+
|
241
|
+
def add(o)
|
242
|
+
@raw.send(:"+=", o.to_scala)
|
243
|
+
self
|
244
|
+
end
|
245
|
+
|
246
|
+
def delete(o)
|
247
|
+
@raw.send(:"-=", o.to_scala)
|
248
|
+
self
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
class Tuple
|
254
|
+
include Common
|
255
|
+
Common.fake_identity self, Array
|
256
|
+
|
257
|
+
def initialize(raw, size)
|
258
|
+
super(raw)
|
259
|
+
@size = size
|
260
|
+
end
|
261
|
+
|
262
|
+
def size
|
263
|
+
@size
|
264
|
+
end
|
265
|
+
|
266
|
+
def blank?
|
267
|
+
false
|
268
|
+
end
|
269
|
+
|
270
|
+
def each
|
271
|
+
if block_given?
|
272
|
+
(0...size).each do |index|
|
273
|
+
yield self[index]
|
274
|
+
end
|
275
|
+
self
|
276
|
+
else
|
277
|
+
Enumerator.new do |yielder|
|
278
|
+
self.each { |item| yielder << item }
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def to_s
|
284
|
+
first = true
|
285
|
+
each_with_object("[") do |item, str|
|
286
|
+
first ? first = false : str << ","
|
287
|
+
str << item.to_s
|
288
|
+
end << "]"
|
289
|
+
end
|
290
|
+
|
291
|
+
def [](index)
|
292
|
+
if index < 0
|
293
|
+
@raw.send("_#{size + index + 1}")
|
294
|
+
elsif index >= size
|
295
|
+
nil
|
296
|
+
else
|
297
|
+
@raw.send("_#{index + 1}")
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
def []=(index, value)
|
302
|
+
raise ImmutableException,
|
303
|
+
"Cannot assign #{value} to index #{index} on #{self
|
304
|
+
}: collection immutable"
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
# Scala <-> Ruby interoperability.
|
310
|
+
class Object
|
311
|
+
def to_scala
|
312
|
+
case self
|
313
|
+
when JRuby::ScalaSupport::Common
|
314
|
+
self.scala_collection
|
315
|
+
when Hash
|
316
|
+
Java::jruby.collection.MapWrapper.new(self)
|
317
|
+
when Set
|
318
|
+
Java::jruby.collection.SetWrapper.new(self)
|
319
|
+
when Array
|
320
|
+
Java::jruby.collection.ListWrapper.new(self)
|
321
|
+
when Symbol
|
322
|
+
Java::scala.Symbol.apply(to_s)
|
323
|
+
else
|
324
|
+
self.to_java
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def from_scala
|
329
|
+
case self
|
330
|
+
when Java::jruby.collection.MapWrapper
|
331
|
+
self.rubyHash
|
332
|
+
when Java::scala.collection.mutable.Map
|
333
|
+
JRuby::ScalaSupport::Map::Mutable.new(self)
|
334
|
+
when Java::scala.collection.Map, Java::scala.collection.immutable.Map
|
335
|
+
JRuby::ScalaSupport::Map::Immutable.new(self)
|
336
|
+
when Java::jruby.collection.ListWrapper
|
337
|
+
self.rubyArray
|
338
|
+
when Java::scala.collection.mutable.Seq
|
339
|
+
JRuby::ScalaSupport::Seq::Mutable.new(self)
|
340
|
+
when Java::scala.collection.Seq, Java::scala.collection.immutable.Seq
|
341
|
+
JRuby::ScalaSupport::Seq::Immutable.new(self)
|
342
|
+
when Java::scala.Product
|
343
|
+
match = self.class.to_s.match(/^Java::Scala::Tuple(\d+)$/)
|
344
|
+
if match
|
345
|
+
size = match[1].to_i
|
346
|
+
JRuby::ScalaSupport::Tuple.new(self, size)
|
347
|
+
else
|
348
|
+
self
|
349
|
+
end
|
350
|
+
when Java::jruby.collection.SetWrapper
|
351
|
+
self.rubySet
|
352
|
+
when Java::scala.collection.mutable.Set
|
353
|
+
JRuby::ScalaSupport::Set::Mutable.new(self)
|
354
|
+
when Java::scala.collection.Set, Java::scala.collection.immutable.Set,
|
355
|
+
JRuby::ScalaSupport::Set::Immutable.new(self)
|
356
|
+
else
|
357
|
+
self
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
module Kernel
|
363
|
+
def Some(value); Java::scala.Some.new(value); end
|
364
|
+
None = Java::jruby.collection.Utils.None
|
365
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jruby-scala-collections
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Artūras Šlajus
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-23 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: Interoperability layer for passing JRuby & Scala collections back and forth. See README.md for more info.
|
15
|
+
email: arturas.slajus@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/jruby/scala_support.rb
|
21
|
+
- README.md
|
22
|
+
- ext/dist/collections.jar
|
23
|
+
homepage: http://github.com/arturaz/jruby-scala-collections
|
24
|
+
licenses: []
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
none: false
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
none: false
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 1.8.15
|
44
|
+
signing_key:
|
45
|
+
specification_version: 3
|
46
|
+
summary: Compiled against JRuby 1.6.7/Scala 2.9.2
|
47
|
+
test_files: []
|
48
|
+
...
|