diametric 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,165 @@
1
+ package diametric;
2
+
3
+ import java.util.Iterator;
4
+
5
+ import org.jruby.RubyArray;
6
+ import org.jruby.RubyClass;
7
+ import org.jruby.RubyFixnum;
8
+ import org.jruby.runtime.Block;
9
+ import org.jruby.runtime.ThreadContext;
10
+ import org.jruby.runtime.builtin.IRubyObject;
11
+
12
+ import clojure.lang.PersistentVector;
13
+ import clojure.lang.Var;
14
+
15
+ class DiametricCommon {
16
+ IRubyObject collect(ThreadContext context, Block block, Iterator<Object> itr) {
17
+ RubyArray ary = context.getRuntime().newArray();
18
+ while (itr.hasNext()) {
19
+ IRubyObject next = DiametricUtils.convertJavaToRuby(context, itr.next());
20
+ ary.callMethod(context, "<<", block.yield(context, next));
21
+ }
22
+ return ary;
23
+ }
24
+
25
+ IRubyObject count(ThreadContext context, IRubyObject arg, Object target) {
26
+ try {
27
+ Var count_value_fn = null;
28
+ if (DiametricService.fnMap.containsKey("count-value")) {
29
+ count_value_fn = DiametricService.fnMap.get("count-value");
30
+ } else {
31
+ Var var = DiametricService.getFn("clojure.core", "load-string");
32
+ count_value_fn = (Var)var.invoke("(defn count-value [v array] (count (filterv (partial = v) array)))");
33
+ DiametricService.fnMap.put("count-value", count_value_fn);
34
+ }
35
+ Object value = DiametricUtils.convertRubyToJava(context, arg);
36
+ return context.getRuntime().newFixnum((Integer)count_value_fn.invoke(value, target));
37
+ } catch (Throwable t) {
38
+ throw context.getRuntime().newRuntimeError(t.getMessage());
39
+ }
40
+ }
41
+
42
+ IRubyObject count(ThreadContext context, Block block, Iterator<Object> itr) {
43
+ Long count = 0L;
44
+ while (itr.hasNext()) {
45
+ IRubyObject next = DiametricUtils.convertJavaToRuby(context, itr.next());
46
+ if (block.yield(context, next).isTrue()) {
47
+ count++;
48
+ }
49
+ }
50
+ return context.getRuntime().newFixnum(count);
51
+ }
52
+
53
+ IRubyObject empty_p(ThreadContext context, Object target) {
54
+ try {
55
+ Var var = DiametricService.getFn("clojure.core", "empty?");
56
+ if ((Boolean)var.invoke(target)) {
57
+ return context.getRuntime().getTrue();
58
+ } else {
59
+ return context.getRuntime().getFalse();
60
+ }
61
+ } catch (Throwable t) {
62
+ throw context.getRuntime().newRuntimeError(t.getMessage());
63
+ }
64
+ }
65
+
66
+ IRubyObject drop_or_take(ThreadContext context, Long n, Object target) {
67
+ try {
68
+ Var drop_or_take_fn = null;
69
+ if (DiametricService.fnMap.containsKey("drop-or-take")) {
70
+ drop_or_take_fn = DiametricService.fnMap.get("drop-or-take");
71
+ } else {
72
+ Var var = DiametricService.getFn("clojure.core", "load-string");
73
+ drop_or_take_fn = (Var)var.invoke("(defn drop-or-take [n target] (apply vector (drop n target)))");
74
+ DiametricService.fnMap.put("drop-or-take", drop_or_take_fn);
75
+ }
76
+ PersistentVector value = (PersistentVector)drop_or_take_fn.invoke(n, target);
77
+ RubyClass clazz = (RubyClass) context.getRuntime().getClassFromPath("Diametric::Persistence::Collection");
78
+ DiametricCollection ruby_collection = (DiametricCollection)clazz.allocate();
79
+ ruby_collection.init(value);
80
+ return ruby_collection;
81
+ } catch (Throwable t) {
82
+ throw context.getRuntime().newRuntimeError(t.getMessage());
83
+ }
84
+ }
85
+
86
+ IRubyObject drop_while(ThreadContext context, Block block, Iterator<Object> itr) {
87
+ RubyArray ary = context.getRuntime().newArray();
88
+ while (itr.hasNext()) {
89
+ IRubyObject next = DiametricUtils.convertJavaToRuby(context, itr.next());
90
+ if (block.yield(context, next).isTrue()) {
91
+ continue;
92
+ } else {
93
+ ary.callMethod(context, "<<", next);
94
+ break;
95
+ }
96
+ }
97
+ while (itr.hasNext()) {
98
+ ary.callMethod(context, "<<", DiametricUtils.convertJavaToRuby(context, itr.next()));
99
+ }
100
+ return ary;
101
+ }
102
+
103
+ void each(ThreadContext context, Block block, Iterator<Object> itr) {
104
+ while (itr.hasNext()) {
105
+ IRubyObject next = DiametricUtils.convertJavaToRuby(context, itr.next());
106
+ block.yield(context, next);
107
+ }
108
+ }
109
+
110
+ IRubyObject first(ThreadContext context, Object target) {
111
+ try {
112
+ Var var = DiametricService.getFn("clojure.core", "first");
113
+ return DiametricUtils.convertJavaToRuby(context, var.invoke(target));
114
+ } catch (Throwable t) {
115
+ throw context.getRuntime().newRuntimeError(t.getMessage());
116
+ }
117
+ }
118
+
119
+ IRubyObject first(ThreadContext context, Long n, Object target) {
120
+ try {
121
+ Var first_n_fn = null;
122
+ if (DiametricService.fnMap.containsKey("first-n")) {
123
+ first_n_fn = DiametricService.fnMap.get("first-n");
124
+ } else {
125
+ Var var = DiametricService.getFn("clojure.core", "load-string");
126
+ first_n_fn = (Var)var.invoke("(defn first-n [n target] (apply vector (take n target)))");
127
+ DiametricService.fnMap.put("first-n", first_n_fn);
128
+ }
129
+ PersistentVector value = (PersistentVector)first_n_fn.invoke(n, target);
130
+ RubyClass clazz = (RubyClass) context.getRuntime().getClassFromPath("Diametric::Persistence::Collection");
131
+ DiametricCollection ruby_collection = (DiametricCollection)clazz.allocate();
132
+ ruby_collection.init(value);
133
+ return ruby_collection;
134
+ } catch (Throwable t) {
135
+ throw context.getRuntime().newRuntimeError(t.getMessage());
136
+ }
137
+ }
138
+
139
+ IRubyObject hash(ThreadContext context, Object target) {
140
+ try {
141
+ Var var = DiametricService.getFn("clojure.core", "hash");
142
+ Integer hash_value = (Integer)var.invoke(target);
143
+ return context.getRuntime().newFixnum(hash_value);
144
+ } catch (Throwable t) {
145
+ throw context.getRuntime().newRuntimeError(t.getMessage());
146
+ }
147
+ }
148
+
149
+ IRubyObject to_s(ThreadContext context, Object target) {
150
+ try {
151
+ Var to_s_fn = null;
152
+ if (DiametricService.fnMap.containsKey("to-s")) {
153
+ to_s_fn = DiametricService.fnMap.get("to-s");
154
+ } else {
155
+ Var var = DiametricService.getFn("clojure.core", "load-string");
156
+ String fn = "(defn to-s [coll] (str (reduce str \"[\" (interpose \", \" coll)) \"]\"))";
157
+ to_s_fn = (Var)var.invoke(fn);
158
+ DiametricService.fnMap.put("to-s", to_s_fn);
159
+ }
160
+ return context.getRuntime().newString((String)to_s_fn.invoke(target));
161
+ } catch (Throwable t) {
162
+ throw context.getRuntime().newRuntimeError(t.getMessage());
163
+ }
164
+ }
165
+ }
@@ -43,10 +43,17 @@ public class DiametricDatabase extends RubyObject {
43
43
 
44
44
  @JRubyMethod
45
45
  public IRubyObject entity(ThreadContext context, IRubyObject arg) {
46
- if (!(arg instanceof RubyFixnum)) {
47
- throw context.getRuntime().newArgumentError("Argument should be Fixnum");
46
+ Long entityId = null;
47
+ if (arg instanceof RubyFixnum) {
48
+ entityId = (Long) arg.toJava(Long.class);
49
+ } else if (arg instanceof DiametricObject) {
50
+ if (((DiametricObject)arg).toJava() instanceof Long) {
51
+ entityId = (Long)((DiametricObject)arg).toJava();
52
+ }
53
+ }
54
+ if (entityId == null) {
55
+ throw context.getRuntime().newArgumentError("Argument should be Fixnum or dbid object");
48
56
  }
49
- Long entityId = (Long) arg.toJava(Long.class);
50
57
  try {
51
58
  Entity entity = (Entity) clojure.lang.RT.var("datomic.api", "entity").invoke(database, entityId);
52
59
  RubyClass clazz = (RubyClass)context.getRuntime().getClassFromPath("Diametric::Persistence::Entity");
@@ -261,10 +261,6 @@ public class DiametricPeer extends RubyModule {
261
261
  for (int i=0; i<inputs.length; i++) {
262
262
  inputs[i] = DiametricUtils.convertRubyToJava(context, ruby_inputs.shift(context));
263
263
  }
264
- //System.out.println("OH INPUTS ARE: ");
265
- //for (int i=0; i<inputs.length; i++) {
266
- // System.out.println("OH: " + inputs[i]);
267
- //}
268
264
  results = (Collection<List<Object>>) clojure.lang.RT.var("datomic.api", "q").invoke(query, database, inputs);
269
265
  }
270
266
  } else {
@@ -279,6 +275,11 @@ public class DiametricPeer extends RubyModule {
279
275
  }
280
276
 
281
277
  if (results == null) return context.getRuntime().getNil();
278
+ RubyClass clazz = (RubyClass)context.getRuntime().getClassFromPath("Diametric::Persistence::Set");
279
+ DiametricSet diametric_set = (DiametricSet)clazz.allocate();
280
+ diametric_set.init(results);
281
+ return diametric_set;
282
+ /*
282
283
  RubyArray ruby_results = RubyArray.newArray(context.getRuntime());
283
284
  for (List list : results) {
284
285
  RubyArray ruby_elements = RubyArray.newArray(context.getRuntime());
@@ -289,6 +290,7 @@ public class DiametricPeer extends RubyModule {
289
290
  ruby_results.append(ruby_elements);
290
291
  }
291
292
  return ruby_results;
293
+ */
292
294
  }
293
295
 
294
296
  private static List<RubyModule> bases = new ArrayList<RubyModule>();
@@ -411,4 +413,10 @@ public class DiametricPeer extends RubyModule {
411
413
  throw runtime.newArgumentError("Arguments should be 'database, dbid, query_string'");
412
414
  }
413
415
  }
416
+
417
+ @JRubyMethod(meta=true)
418
+ public static IRubyObject get_set(ThreadContext context, IRubyObject klazz) {
419
+ IRubyObject set = context.getRuntime().getClass("Set");
420
+ return context.getRuntime().getNil();
421
+ }
414
422
  }
@@ -1,6 +1,9 @@
1
1
  package diametric;
2
2
 
3
3
  import java.io.IOException;
4
+ import java.util.Collections;
5
+ import java.util.HashMap;
6
+ import java.util.Map;
4
7
 
5
8
  import org.jruby.Ruby;
6
9
  import org.jruby.RubyClass;
@@ -9,6 +12,9 @@ import org.jruby.runtime.ObjectAllocator;
9
12
  import org.jruby.runtime.builtin.IRubyObject;
10
13
  import org.jruby.runtime.load.BasicLibraryService;
11
14
 
15
+ import clojure.lang.RT;
16
+ import clojure.lang.Var;
17
+
12
18
  public class DiametricService implements BasicLibraryService {
13
19
 
14
20
  @Override
@@ -28,8 +34,11 @@ public class DiametricService implements BasicLibraryService {
28
34
  RubyClass diametric_object = persistence.defineClassUnder("Object", runtime.getObject(), DIAMETRIC_OBJECT_ALLOCATOR);
29
35
  diametric_object.defineAnnotatedMethods(DiametricObject.class);
30
36
 
31
- RubyClass diametric_query_result = persistence.defineClassUnder("Collection", runtime.getObject(), COLLECTION_ALLOCATOR);
32
- diametric_query_result.defineAnnotatedMethods(DiametricCollection.class);
37
+ RubyClass diametric_collection = persistence.defineClassUnder("Collection", runtime.getObject(), COLLECTION_ALLOCATOR);
38
+ diametric_collection.defineAnnotatedMethods(DiametricCollection.class);
39
+
40
+ RubyClass diametric_set = persistence.defineClassUnder("Set", runtime.getObject(), SET_ALLOCATOR);
41
+ diametric_set.defineAnnotatedMethods(DiametricSet.class);
33
42
 
34
43
  RubyClass diametric_listenable = persistence.defineClassUnder("ListenableFuture", runtime.getObject(), LISTENABLE_ALLOCATOR);
35
44
  diametric_listenable.defineAnnotatedMethods(DiametricListenableFuture.class);
@@ -78,6 +87,12 @@ public class DiametricService implements BasicLibraryService {
78
87
  }
79
88
  };
80
89
 
90
+ public static final ObjectAllocator SET_ALLOCATOR = new ObjectAllocator() {
91
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
92
+ return new DiametricSet(runtime, klazz);
93
+ }
94
+ };
95
+
81
96
  public static final ObjectAllocator LISTENABLE_ALLOCATOR = new ObjectAllocator() {
82
97
  public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
83
98
  return new DiametricListenableFuture(runtime, klazz);
@@ -96,7 +111,25 @@ public class DiametricService implements BasicLibraryService {
96
111
  }
97
112
  };
98
113
 
114
+ static Map<String, Var> fnMap = null;
115
+
99
116
  private void setupClojureRT() {
100
117
  clojure.lang.RT.var("clojure.core", "require").invoke(clojure.lang.Symbol.intern("datomic.api"));
118
+ clojure.lang.RT.var("clojure.core", "require").invoke(clojure.lang.Symbol.intern("clojure.string"));
119
+ if (fnMap == null) {
120
+ fnMap = new HashMap<String, Var>();
121
+ Collections.synchronizedMap(fnMap);
122
+ }
123
+ }
124
+
125
+ static Var getFn(String namespace, String fn) {
126
+ String fullname = namespace + "/" + fn;
127
+ if (fnMap.containsKey(fullname)) {
128
+ return fnMap.get(fullname);
129
+ } else {
130
+ Var var = RT.var(namespace, fn);
131
+ fnMap.put(fullname, var);
132
+ return var;
133
+ }
101
134
  }
102
135
  }
@@ -0,0 +1,270 @@
1
+ package diametric;
2
+
3
+ import java.util.Collection;
4
+ import java.util.HashSet;
5
+ import java.util.Iterator;
6
+ import java.util.List;
7
+ import java.util.Set;
8
+
9
+ import org.jruby.Ruby;
10
+ import org.jruby.RubyArray;
11
+ import org.jruby.RubyClass;
12
+ import org.jruby.RubyFixnum;
13
+ import org.jruby.RubyHash;
14
+ import org.jruby.RubyObject;
15
+ import org.jruby.anno.JRubyClass;
16
+ import org.jruby.anno.JRubyMethod;
17
+ import org.jruby.javasupport.JavaUtil;
18
+ import org.jruby.runtime.Block;
19
+ import org.jruby.runtime.ThreadContext;
20
+ import org.jruby.runtime.builtin.IRubyObject;
21
+
22
+ import clojure.lang.IPersistentSet;
23
+ import clojure.lang.PersistentHashMap;
24
+ import clojure.lang.PersistentHashSet;
25
+ import clojure.lang.Var;
26
+
27
+ @JRubyClass(name = "Diametric::Persistence::Set")
28
+ public class DiametricSet extends RubyObject {
29
+ private static final long serialVersionUID = 2565282201531713809L;
30
+ private Set<Object> set = null; // java.util.HashSet or clojure.lang.PersistentHashSet
31
+ private Integer count = null; // unable to count the vector size that exceeds Integer
32
+ private DiametricCommon common = null;
33
+
34
+ public DiametricSet(Ruby runtime, RubyClass klazz) {
35
+ super(runtime, klazz);
36
+ }
37
+
38
+ void init(Object value) {
39
+ if ((value instanceof PersistentHashSet) || (value instanceof HashSet)) {
40
+ set = (Set)value;
41
+ } else if (value instanceof List) {
42
+ set = (Set)PersistentHashSet.create((List)value);
43
+ } else {
44
+ throw new RuntimeException("Wrong type for Set");
45
+ }
46
+ common = new DiametricCommon();
47
+ }
48
+
49
+ PersistentHashSet convertHashSetToPersistentHashSet(Set set) {
50
+ // bad performance conversion, needs to be careful to use
51
+ return PersistentHashSet.create(set.toArray(new Object[0]));
52
+ }
53
+
54
+ Object toJava() {
55
+ return set;
56
+ }
57
+
58
+ @JRubyMethod(meta=true)
59
+ public static IRubyObject wrap(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
60
+ try {
61
+ Set<Object> s = (Set<Object>)arg.toJava(Set.class);
62
+ RubyClass clazz = (RubyClass) context.getRuntime().getClassFromPath("Diametric::Persistence::Set");
63
+ DiametricSet ruby_set = (DiametricSet)clazz.allocate();
64
+ ruby_set.init(s);
65
+ return ruby_set;
66
+ } catch (Throwable t) {
67
+ throw context.getRuntime().newRuntimeError(t.getMessage());
68
+ }
69
+ }
70
+
71
+ @JRubyMethod
72
+ public IRubyObject to_java(ThreadContext context) {
73
+ return JavaUtil.convertJavaToUsableRubyObject(context.getRuntime(), set);
74
+ }
75
+
76
+ @JRubyMethod(name={"collect", "map"})
77
+ public IRubyObject collect(ThreadContext context, Block block) {
78
+ if (block.isGiven()) {
79
+ return common.collect(context, block, set.iterator());
80
+ }
81
+ return this;
82
+ }
83
+
84
+ @JRubyMethod
85
+ public IRubyObject each(ThreadContext context, Block block) {
86
+ if (block.isGiven()) {
87
+ common.each(context, block, set.iterator());
88
+ }
89
+ return this;
90
+ }
91
+
92
+ @JRubyMethod(name="empty?")
93
+ public IRubyObject empty_p(ThreadContext context) {
94
+ return common.empty_p(context, set);
95
+ }
96
+
97
+ @JRubyMethod(name={"==", "eql?", "equal?"})
98
+ public IRubyObject equal_p(ThreadContext context, IRubyObject arg) {
99
+ if (arg.isNil()) return context.getRuntime().getFalse();
100
+ IPersistentSet other = null;
101
+ if (arg.respondsTo("intersection")) {
102
+ other = DiametricUtils.getPersistentSet(context, arg);
103
+ } else if (arg instanceof HashSet) {
104
+ other = convertHashSetToPersistentHashSet((HashSet)arg);
105
+ } else if (arg instanceof DiametricSet) {
106
+ if (((DiametricSet)arg).toJava() instanceof HashSet) {
107
+ other = convertHashSetToPersistentHashSet((HashSet)((DiametricSet)arg).toJava());
108
+ } else {
109
+ other = (IPersistentSet)((DiametricSet)arg).toJava();
110
+ }
111
+ } else {
112
+ return context.getRuntime().getFalse();
113
+ }
114
+ try {
115
+ Var var = DiametricService.getFn("clojure.core", "=");
116
+ if ((Boolean)var.invoke(set, other)) {
117
+ return context.getRuntime().getTrue();
118
+ } else {
119
+ return context.getRuntime().getFalse();
120
+ }
121
+ } catch(Throwable t) {
122
+ throw context.getRuntime().newRuntimeError(t.getMessage());
123
+ }
124
+ }
125
+
126
+ @JRubyMethod(name={"drop", "take"})
127
+ public IRubyObject drop(ThreadContext context, IRubyObject arg) {
128
+ if (!(arg instanceof RubyFixnum)) {
129
+ throw context.getRuntime().newArgumentError("argument should be Fixnum");
130
+ }
131
+ Long n = (Long)arg.toJava(Long.class);
132
+ if (n < 0) {
133
+ throw context.getRuntime().newArgumentError("negative drop size");
134
+ }
135
+ if (n == 0) return this;
136
+ return common.drop_or_take(context, n, set);
137
+ }
138
+
139
+ @JRubyMethod
140
+ public IRubyObject first(ThreadContext context) {
141
+ Object first = common.first(context, set);
142
+ return DiametricUtils.convertJavaToRuby(context, first);
143
+ }
144
+
145
+ @JRubyMethod
146
+ public IRubyObject group_by(ThreadContext context, Block block) {
147
+ Ruby runtime = context.getRuntime();
148
+ if (block.isGiven()) {
149
+ RubyHash hash_result = new RubyHash(runtime);
150
+ Iterator<Object> itr = set.iterator();
151
+ while (itr.hasNext()) {
152
+ IRubyObject ruby_next = DiametricUtils.convertJavaToRuby(context, itr.next());
153
+ IRubyObject block_result = block.yield(context, ruby_next);
154
+ IRubyObject value = hash_result.callMethod(context, "[]", block_result);
155
+ if (value.isNil()) {
156
+ // new key
157
+ IRubyObject[] args = new IRubyObject[]{block_result, runtime.newArray()};
158
+ value = hash_result.callMethod(context, "[]=", args);
159
+ }
160
+ value.callMethod(context, "<<", ruby_next);
161
+ }
162
+ return hash_result;
163
+ } else {
164
+ return this;
165
+ }
166
+ }
167
+
168
+ @JRubyMethod(name="include?")
169
+ public IRubyObject include_p(ThreadContext context, IRubyObject arg) {
170
+ Object java_object = DiametricUtils.convertRubyToJava(context, arg);
171
+ try {
172
+ Var var = DiametricService.getFn("clojure.core", "contains?");
173
+ if ((Boolean)var.invoke(set, java_object)) {
174
+ return context.getRuntime().getTrue();
175
+ } else {
176
+ return context.getRuntime().getFalse();
177
+ }
178
+ } catch (Throwable t) {
179
+ throw context.getRuntime().newRuntimeError(t.getMessage());
180
+ }
181
+ }
182
+
183
+ @JRubyMethod(name={"&", "intersection"})
184
+ public IRubyObject intersection(ThreadContext context, IRubyObject arg) {
185
+ if (!(arg.respondsTo("intersection"))) throw context.getRuntime().newArgumentError("argument should be a set");
186
+ IPersistentSet other = (IPersistentSet)DiametricUtils.getPersistentSet(context, arg);
187
+ try {
188
+ Var var = DiametricService.getFn("clojure.set", "intersection");
189
+ if (set instanceof HashSet) {
190
+ PersistentHashSet value = convertHashSetToPersistentHashSet(set);
191
+ return DiametricUtils.convertJavaToRuby(context, var.invoke(value, other));
192
+ } else {
193
+ return DiametricUtils.convertJavaToRuby(context, var.invoke(set, other));
194
+ }
195
+ } catch (Throwable t) {
196
+ throw context.getRuntime().newRuntimeError(t.getMessage());
197
+ }
198
+ }
199
+
200
+ private int getCount() {
201
+ if (count == null) {
202
+ Var var = DiametricService.getFn("clojure.core", "count");
203
+ count = (Integer)var.invoke(set);
204
+ }
205
+ return count;
206
+ }
207
+
208
+ @JRubyMethod(name={"length", "size"})
209
+ public IRubyObject size(ThreadContext context) {
210
+ try {
211
+ return context.getRuntime().newFixnum(getCount());
212
+ } catch (Throwable t) {
213
+ throw context.getRuntime().newRuntimeError(t.getMessage());
214
+ }
215
+ }
216
+
217
+ @JRubyMethod
218
+ public IRubyObject to_a(ThreadContext context) {
219
+ try {
220
+ RubyArray array = context.getRuntime().newArray();
221
+ Iterator<Object> itr = set.iterator();
222
+ while (itr.hasNext()) {
223
+ Object value = itr.next();
224
+ array.callMethod(context, "<<", DiametricUtils.convertJavaToRuby(context, value));
225
+ }
226
+ return array;
227
+ } catch (Throwable t) {
228
+ throw context.getRuntime().newRuntimeError(t.getMessage());
229
+ }
230
+ }
231
+
232
+ @JRubyMethod
233
+ public IRubyObject to_s(ThreadContext context) {
234
+ return common.to_s(context, set);
235
+ }
236
+
237
+ @JRubyMethod(name={"|", "union"})
238
+ public IRubyObject union(ThreadContext context, IRubyObject arg) {
239
+ if (!(arg.respondsTo("union"))) throw context.getRuntime().newArgumentError("argument should be a set");
240
+ IPersistentSet other = (IPersistentSet)DiametricUtils.getPersistentSet(context, arg);
241
+ try {
242
+ Var var = DiametricService.getFn("clojure.set", "union");
243
+ if (set instanceof HashSet) {
244
+ PersistentHashSet value = convertHashSetToPersistentHashSet(set);
245
+ return DiametricUtils.getDiametricSet(context, (Set)var.invoke(value, other));
246
+ } else {
247
+ return DiametricUtils.getDiametricSet(context, (Set)var.invoke(set, other));
248
+ }
249
+ } catch (Throwable t) {
250
+ throw context.getRuntime().newRuntimeError(t.getMessage());
251
+ }
252
+ }
253
+
254
+ @JRubyMethod(name={"-", "difference"})
255
+ public IRubyObject difference(ThreadContext context, IRubyObject arg) {
256
+ if (!(arg.respondsTo("difference"))) throw context.getRuntime().newArgumentError("argument should be a set");
257
+ IPersistentSet other = (IPersistentSet)DiametricUtils.getPersistentSet(context, arg);
258
+ try {
259
+ Var var = DiametricService.getFn("clojure.set", "difference");
260
+ if (set instanceof HashSet) {
261
+ PersistentHashSet value = convertHashSetToPersistentHashSet(set);
262
+ return DiametricUtils.getDiametricSet(context, (Set)var.invoke(value, other));
263
+ } else {
264
+ return DiametricUtils.getDiametricSet(context, (Set)var.invoke(set, other));
265
+ }
266
+ } catch (Throwable t) {
267
+ throw context.getRuntime().newRuntimeError(t.getMessage());
268
+ }
269
+ }
270
+ }