Skip to content

Commit abc8bec

Browse files
Merge pull request #422 from ragalie/jruby
JRuby function wrapping support
2 parents 2bd22d6 + 24807e9 commit abc8bec

File tree

11 files changed

+705
-0
lines changed

11 files changed

+705
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# JRuby Adaptor for RxJava
2+
3+
This adaptor improves the success and performance of RxJava when Ruby `Proc` is passed to an RxJava method.
4+
5+
This enables correct and efficient execution of code such as:
6+
7+
```ruby
8+
Observable.from("one", "two", "three").
9+
take(2).
10+
subscribe {|val| puts val}
11+
```
12+
13+
# Usage
14+
15+
Require the JAR file as usual. After requiring the JAR, you must also require the interop code:
16+
17+
```ruby
18+
require "rx/lang/jruby/interop"
19+
```
20+
21+
# Binaries
22+
23+
Binaries and dependency information for Maven, Ivy, Gradle and others can be found at [http://search.maven.org](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22rxjava-jruby%22).
24+
25+
Example for Maven:
26+
27+
```xml
28+
<dependency>
29+
<groupId>com.netflix.rxjava</groupId>
30+
<artifactId>rxjava-jruby</artifactId>
31+
<version>x.y.z</version>
32+
</dependency>
33+
```
34+
35+
and for Ivy:
36+
37+
```xml
38+
<dependency org="com.netflix.rxjava" name="rxjava-jruby" rev="x.y.z" />
39+
```
40+
41+
and for Gradle:
42+
43+
```groovy
44+
compile 'com.netflix.rxjava:rxjava-jruby:x.y.z'
45+
```
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
apply plugin: 'osgi'
2+
3+
repositories {
4+
maven {
5+
url 'http://deux.gemjars.org'
6+
}
7+
mavenCentral()
8+
}
9+
10+
configurations {
11+
rspec
12+
}
13+
14+
sourceSets {
15+
test {
16+
resources {
17+
srcDir 'src/spec/ruby'
18+
}
19+
}
20+
}
21+
22+
dependencies {
23+
compile project(':rxjava-core')
24+
compile 'org.jruby:jruby:1.7+'
25+
provided 'junit:junit-dep:4.10'
26+
provided 'org.mockito:mockito-core:1.8.5'
27+
rspec 'org.jruby:jruby-complete:1.7.4'
28+
rspec 'org.rubygems:rspec:2.14.1'
29+
}
30+
31+
task(rspec, type: JavaExec) {
32+
main 'org.jruby.Main'
33+
classpath configurations.rspec + runtimeClasspath
34+
args 'classpath:bin/rspec', 'src/spec/ruby'
35+
}
36+
37+
tasks.build.dependsOn << 'rspec'
38+
39+
jar {
40+
manifest {
41+
name = 'rxjava-jruby'
42+
instruction 'Bundle-Vendor', 'Netflix'
43+
instruction 'Bundle-DocURL', 'https://github.com/Netflix/RxJava'
44+
instruction 'Import-Package', '!org.junit,!junit.framework,!org.mockito.*,*'
45+
instruction 'Fragment-Host', 'com.netflix.rxjava.core'
46+
}
47+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* Copyright 2013 Netflix, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package rx.lang.jruby;
17+
18+
import org.jruby.RubyProc;
19+
import org.jruby.Ruby;
20+
import org.jruby.runtime.ThreadContext;
21+
import org.jruby.runtime.builtin.IRubyObject;
22+
import org.jruby.javasupport.JavaUtil;
23+
24+
import rx.util.functions.Action;
25+
import rx.util.functions.Action0;
26+
import rx.util.functions.Action1;
27+
import rx.util.functions.Action2;
28+
import rx.util.functions.Action3;
29+
30+
/**
31+
* Concrete wrapper that accepts a {@link RubyProc} and produces any needed Rx {@link Action}.
32+
*
33+
* @param <T1>
34+
* @param <T2>
35+
* @param <T3>
36+
* @param <T4>
37+
*/
38+
public class JRubyActionWrapper<T1, T2, T3, T4> implements Action, Action0, Action1<T1>, Action2<T1, T2>, Action3<T1, T2, T3> {
39+
40+
private final RubyProc proc;
41+
private final ThreadContext context;
42+
private final Ruby runtime;
43+
44+
public JRubyActionWrapper(ThreadContext context, RubyProc proc) {
45+
this.proc = proc;
46+
this.context = context;
47+
this.runtime = context.getRuntime();
48+
}
49+
50+
@Override
51+
public void call() {
52+
IRubyObject[] array = new IRubyObject[0];
53+
proc.call(context, array);
54+
}
55+
56+
@Override
57+
public void call(T1 t1) {
58+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1)};
59+
proc.call(context, array);
60+
}
61+
62+
@Override
63+
public void call(T1 t1, T2 t2) {
64+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
65+
JavaUtil.convertJavaToRuby(runtime, t2)};
66+
proc.call(context, array);
67+
}
68+
69+
@Override
70+
public void call(T1 t1, T2 t2, T3 t3) {
71+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
72+
JavaUtil.convertJavaToRuby(runtime, t2),
73+
JavaUtil.convertJavaToRuby(runtime, t3)};
74+
proc.call(context, array);
75+
}
76+
77+
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/**
2+
* Copyright 2013 Netflix, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package rx.lang.jruby;
17+
18+
import org.jruby.RubyProc;
19+
import org.jruby.Ruby;
20+
import org.jruby.runtime.ThreadContext;
21+
import org.jruby.runtime.builtin.IRubyObject;
22+
import org.jruby.javasupport.JavaUtil;
23+
24+
import rx.util.functions.Func0;
25+
import rx.util.functions.Func1;
26+
import rx.util.functions.Func2;
27+
import rx.util.functions.Func3;
28+
import rx.util.functions.Func4;
29+
import rx.util.functions.Func5;
30+
import rx.util.functions.Func6;
31+
import rx.util.functions.Func7;
32+
import rx.util.functions.Func8;
33+
import rx.util.functions.Func9;
34+
import rx.util.functions.FuncN;
35+
import rx.util.functions.Function;
36+
37+
/**
38+
* Concrete wrapper that accepts a {@link RubyProc} and produces any needed Rx {@link Function}.
39+
*
40+
* @param <T1>
41+
* @param <T2>
42+
* @param <T3>
43+
* @param <T4>
44+
* @param <R>
45+
*/
46+
public class JRubyFunctionWrapper<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> implements
47+
Func0<R>,
48+
Func1<T1, R>,
49+
Func2<T1, T2, R>,
50+
Func3<T1, T2, T3, R>,
51+
Func4<T1, T2, T3, T4, R>,
52+
Func5<T1, T2, T3, T4, T5, R>,
53+
Func6<T1, T2, T3, T4, T5, T6, R>,
54+
Func7<T1, T2, T3, T4, T5, T6, T7, R>,
55+
Func8<T1, T2, T3, T4, T5, T6, T7, T8, R>,
56+
Func9<T1, T2, T3, T4, T5, T6, T7, T8, T9, R>,
57+
FuncN<R> {
58+
59+
private final RubyProc proc;
60+
private final ThreadContext context;
61+
private final Ruby runtime;
62+
63+
public JRubyFunctionWrapper(ThreadContext context, RubyProc proc) {
64+
this.proc = proc;
65+
this.context = context;
66+
this.runtime = context.getRuntime();
67+
}
68+
69+
@Override
70+
public R call() {
71+
IRubyObject[] array = new IRubyObject[0];
72+
return (R) proc.call(context, array);
73+
}
74+
75+
@Override
76+
public R call(T1 t1) {
77+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1)};
78+
return (R) proc.call(context, array);
79+
}
80+
81+
@Override
82+
public R call(T1 t1, T2 t2) {
83+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
84+
JavaUtil.convertJavaToRuby(runtime, t2)};
85+
return (R) proc.call(context, array);
86+
}
87+
88+
@Override
89+
public R call(T1 t1, T2 t2, T3 t3) {
90+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
91+
JavaUtil.convertJavaToRuby(runtime, t2),
92+
JavaUtil.convertJavaToRuby(runtime, t3)};
93+
return (R) proc.call(context, array);
94+
}
95+
96+
@Override
97+
public R call(T1 t1, T2 t2, T3 t3, T4 t4) {
98+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
99+
JavaUtil.convertJavaToRuby(runtime, t2),
100+
JavaUtil.convertJavaToRuby(runtime, t3),
101+
JavaUtil.convertJavaToRuby(runtime, t4)};
102+
return (R) proc.call(context, array);
103+
}
104+
105+
@Override
106+
public R call(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) {
107+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
108+
JavaUtil.convertJavaToRuby(runtime, t2),
109+
JavaUtil.convertJavaToRuby(runtime, t3),
110+
JavaUtil.convertJavaToRuby(runtime, t4),
111+
JavaUtil.convertJavaToRuby(runtime, t5)};
112+
return (R) proc.call(context, array);
113+
}
114+
115+
@Override
116+
public R call(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) {
117+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
118+
JavaUtil.convertJavaToRuby(runtime, t2),
119+
JavaUtil.convertJavaToRuby(runtime, t3),
120+
JavaUtil.convertJavaToRuby(runtime, t4),
121+
JavaUtil.convertJavaToRuby(runtime, t5),
122+
JavaUtil.convertJavaToRuby(runtime, t6)};
123+
return (R) proc.call(context, array);
124+
}
125+
126+
@Override
127+
public R call(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) {
128+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
129+
JavaUtil.convertJavaToRuby(runtime, t2),
130+
JavaUtil.convertJavaToRuby(runtime, t3),
131+
JavaUtil.convertJavaToRuby(runtime, t4),
132+
JavaUtil.convertJavaToRuby(runtime, t5),
133+
JavaUtil.convertJavaToRuby(runtime, t6),
134+
JavaUtil.convertJavaToRuby(runtime, t7)};
135+
return (R) proc.call(context, array);
136+
}
137+
138+
@Override
139+
public R call(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) {
140+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
141+
JavaUtil.convertJavaToRuby(runtime, t2),
142+
JavaUtil.convertJavaToRuby(runtime, t3),
143+
JavaUtil.convertJavaToRuby(runtime, t4),
144+
JavaUtil.convertJavaToRuby(runtime, t5),
145+
JavaUtil.convertJavaToRuby(runtime, t6),
146+
JavaUtil.convertJavaToRuby(runtime, t7),
147+
JavaUtil.convertJavaToRuby(runtime, t8)};
148+
return (R) proc.call(context, array);
149+
}
150+
151+
@Override
152+
public R call(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) {
153+
IRubyObject[] array = {JavaUtil.convertJavaToRuby(runtime, t1),
154+
JavaUtil.convertJavaToRuby(runtime, t2),
155+
JavaUtil.convertJavaToRuby(runtime, t3),
156+
JavaUtil.convertJavaToRuby(runtime, t4),
157+
JavaUtil.convertJavaToRuby(runtime, t5),
158+
JavaUtil.convertJavaToRuby(runtime, t6),
159+
JavaUtil.convertJavaToRuby(runtime, t7),
160+
JavaUtil.convertJavaToRuby(runtime, t8),
161+
JavaUtil.convertJavaToRuby(runtime, t9)};
162+
return (R) proc.call(context, array);
163+
}
164+
165+
@Override
166+
public R call(Object... args) {
167+
IRubyObject[] array = new IRubyObject[args.length];
168+
for (int i = 0; i < args.length; i++) {
169+
array[i] = JavaUtil.convertJavaToRuby(runtime, args[i]);
170+
}
171+
return (R) proc.call(context, array);
172+
}
173+
}

0 commit comments

Comments
 (0)