Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f6b5d20dcafe
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0bba611d7e0a
Choose a head ref
  • 3 commits
  • 2 files changed
  • 1 contributor

Commits on Feb 17, 2017

  1. Copy the full SHA
    47e07f1 View commit details
  2. Copy the full SHA
    f555a75 View commit details
  3. Copy the full SHA
    0bba611 View commit details
Showing with 40 additions and 21 deletions.
  1. +33 −21 core/src/main/java/org/jruby/RubyComplex.java
  2. +7 −0 spec/ruby/shared/complex/Complex.rb
54 changes: 33 additions & 21 deletions core/src/main/java/org/jruby/RubyComplex.java
Original file line number Diff line number Diff line change
@@ -68,6 +68,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.callsite.RespondToCallSite;
import org.jruby.util.ByteList;
import org.jruby.util.Numeric;

@@ -82,12 +83,13 @@
@JRubyClass(name = "Complex", parent = "Numeric")
public class RubyComplex extends RubyNumeric {

private static final String[] UNDEFINED = new String[]{
"<", "<=", "<=>", ">", ">=", "between?", "divmod", "floor", "ceil", "modulo", "round", "step",
"truncate", "positive?", "negative?"
};

public static RubyClass createComplexClass(Ruby runtime) {
final String[] UNDEFINED = new String[]{
"<", "<=", "<=>", ">", ">=",
"between?", "divmod", "floor", "ceil", "modulo",
"round", "step", "truncate", "positive?", "negative?"
};

RubyClass complexc = runtime.defineClass("Complex", runtime.getNumeric(), COMPLEX_ALLOCATOR);
runtime.setComplex(complexc);

@@ -294,9 +296,9 @@ private static void realCheck(ThreadContext context, IRubyObject num) {
case RATIONAL:
break;
default:
if (!(num instanceof RubyNumeric ) || !f_real_p(context, num).isTrue()) {
if (!(num instanceof RubyNumeric ) || !f_real_p(context, num).isTrue()) {
throw context.runtime.newTypeError("not a real");
}
}
}
}

@@ -311,15 +313,16 @@ private static IRubyObject canonicalizeInternal(ThreadContext context, IRubyObje
canonicalization)
return real;
}
if (f_real_p(context, real).isTrue() &&
f_real_p(context, image).isTrue()) {
if (f_real_p(context, real).isTrue() && f_real_p(context, image).isTrue()) {
return new RubyComplex(context.runtime, clazz, real, image);
} else if (f_real_p(context, real).isTrue()) {
}
if (f_real_p(context, real).isTrue()) {
RubyComplex complex = (RubyComplex)image;
return new RubyComplex(context.runtime, clazz,
f_sub(context, real, complex.image),
f_add(context, RubyFixnum.zero(context.runtime), complex.real));
} else if (f_real_p(context, image).isTrue()) {
}
if (f_real_p(context, image).isTrue()) {
RubyComplex complex = (RubyComplex)real;
return new RubyComplex(context.runtime, clazz,
complex.real,
@@ -431,33 +434,41 @@ public static IRubyObject convert(ThreadContext context, IRubyObject clazz, IRub
*
*/
@JRubyMethod(name = "convert", meta = true, visibility = Visibility.PRIVATE)
public static IRubyObject convert(ThreadContext context, IRubyObject recv, IRubyObject a1) {
return convertCommon(context, recv, a1, context.runtime.getNil());
public static IRubyObject convert(ThreadContext context, IRubyObject recv, IRubyObject arg) {
return convertCommon(context, recv, arg, context.nil, true);
}

private static boolean responds_to_to_c(ThreadContext context, IRubyObject obj) {
return respond_to_to_c.respondsTo(context, obj, obj);
}

// TODO: wasn't sure whether to put this on NumericSites, here for now - should move
static final RespondToCallSite respond_to_to_c = new RespondToCallSite("to_c");

/** nucomp_s_convert
*
*/
@JRubyMethod(name = "convert", meta = true, visibility = Visibility.PRIVATE)
public static IRubyObject convert(ThreadContext context, IRubyObject recv, IRubyObject a1, IRubyObject a2) {
return convertCommon(context, recv, a1, a2);
return convertCommon(context, recv, a1, a2, false);
}

private static IRubyObject convertCommon(ThreadContext context, IRubyObject recv, IRubyObject a1, IRubyObject a2) {
private static IRubyObject convertCommon(ThreadContext context, IRubyObject recv,
IRubyObject a1, IRubyObject a2, final boolean singleArg) {
if (a1 instanceof RubyString) a1 = str_to_c_strict(context, a1);
if (a2 instanceof RubyString) a2 = str_to_c_strict(context, a2);

if (a1 instanceof RubyComplex) {
RubyComplex a1Complex = (RubyComplex)a1;
if (k_exact_p(a1Complex.image) && f_zero_p(context, a1Complex.image)) {
a1 = a1Complex.real;
RubyComplex a1c = (RubyComplex) a1;
if (k_exact_p(a1c.image) && f_zero_p(context, a1c.image)) {
a1 = a1c.real;
}
}

if (a2 instanceof RubyComplex) {
RubyComplex a2Complex = (RubyComplex)a2;
if (k_exact_p(a2Complex.image) && f_zero_p(context, a2Complex.image)) {
a2 = a2Complex.real;
RubyComplex a2c = (RubyComplex) a2;
if (k_exact_p(a2c.image) && f_zero_p(context, a2c.image)) {
a2 = a2c.real;
}
}

@@ -467,6 +478,7 @@ private static IRubyObject convertCommon(ThreadContext context, IRubyObject recv

if (a2.isNil()) {
if (a1 instanceof RubyNumeric && !f_real_p(context, a1).isTrue()) return a1;
if (singleArg && responds_to_to_c(context, a1) ) return a1.callMethod(context, "to_c");
return newInstance(context, recv, a1);
} else {
if (a1 instanceof RubyNumeric && a2 instanceof RubyNumeric &&
7 changes: 7 additions & 0 deletions spec/ruby/shared/complex/Complex.rb
Original file line number Diff line number Diff line change
@@ -62,6 +62,13 @@
it "needs to be reviewed for spec completeness"
end

describe "when passed an Objectc which responds to #to_c" do
it "returns the passed argument" do
obj = Object.new; def obj.to_c; 1i end
Complex(obj).should == Complex(0, 1)
end
end

describe "when passed a Numeric which responds to #real? with false" do
it "returns the passed argument" do
n = mock_numeric("unreal")