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: ff0d7359d1cc
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: bab8f0aafd44
Choose a head ref
  • 4 commits
  • 4 files changed
  • 1 contributor

Commits on May 27, 2016

  1. Copy the full SHA
    6ca6f1f View commit details
  2. Copy the full SHA
    86acf47 View commit details
  3. Copy the full SHA
    7c4997f View commit details
  4. Document and reorg new{Name,NoMethod}Error methods.

    Some of these use the format string, some don't. See #3934.
    headius committed May 27, 2016
    Copy the full SHA
    bab8f0a View commit details
131 changes: 104 additions & 27 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -3956,45 +3956,56 @@ public RaiseException newIllegalSequence(String message) {
return newRaiseException(getClass("Iconv").getClass("IllegalSequence"), message);
}

public RaiseException newNoMethodError(String message, String name, IRubyObject args) {
return new RaiseException(new RubyNoMethodError(this, getNoMethodError(), message, name, args), true);
}

public RaiseException newNameError(String message, String name) {
return newNameError(message, name, null);
}

@Deprecated
public RaiseException newNameErrorObject(String message, IRubyObject name) {
RubyException error = new RubyNameError(this, getNameError(), message, name);

return new RaiseException(error, false);
}

public RaiseException newNameError(String message, String name, Throwable origException) {
return newNameError(message, name, origException, false);
}

/**
* Construct a NameError that formats its message with an sprintf format string.
*
* The arguments given to sprintf are as follows:
*
* 0: the name that failed
* 1: the receiver object that failed
* 2: a ":" character for non-singleton recv, blank otherwise
* 3: the name of the a non-singleton recv's class, blank if recv is a singleton
*
* Passing a string with no format characters will warn in verbose mode and error in debug mode.
*
* See jruby/jruby#3934.
*
* @param message an sprintf format string for the message
* @param recv the receiver object
* @param name the name that failed
* @return a new NameError
*/
public RaiseException newNameError(String message, IRubyObject recv, IRubyObject name) {
IRubyObject msg = new RubyNameError.RubyNameErrorMessage(this, message, recv, name);
RubyException err = RubyNameError.newNameError(getNameError(), msg, name);

return new RaiseException(err);
}

/**
* Construct a NameError that formats its message with an sprintf format string.
*
* This version just accepts a java.lang.String for the name.
*
* @see Ruby#newNameError(String, IRubyObject, IRubyObject)
*/
public RaiseException newNameError(String message, IRubyObject recv, String name) {
RubySymbol nameSym = newSymbol(name);
return newNameError(message, recv, nameSym);
}

public RaiseException newNoMethodError(String message, IRubyObject recv, String name, RubyArray args) {
RubySymbol nameStr = newSymbol(name);
IRubyObject msg = new RubyNameError.RubyNameErrorMessage(this, message, recv, nameStr);
RubyException err = RubyNoMethodError.newNoMethodError(getNoMethodError(), msg, nameStr, args);

return new RaiseException(err);
}

/**
* Construct a NameError with the given pre-formatted message, name, and optional original exception.
*
* If the original exception is given, and either we are in verbose mode with printWhenVerbose set to true
* or we are in debug mode.
*
* @param message the pre-formatted message for the NameError
* @param name the name that failed
* @param origException the original exception, or null
* @param printWhenVerbose whether to log this exception when verbose mode is enabled
* @return a new NameError
*/
public RaiseException newNameError(String message, String name, Throwable origException, boolean printWhenVerbose) {
if (origException != null) {
if (printWhenVerbose && isVerbose()) {
@@ -4007,6 +4018,65 @@ public RaiseException newNameError(String message, String name, Throwable origEx
return new RaiseException(new RubyNameError(this, getNameError(), message, name), false);
}

/**
* Construct a NameError with a pre-formatted message and name.
*
* This is the same as calling {@link #newNameError(String, String, Throwable)} with a null
* originating exception.
*
* @param message the pre-formatted message for the error
* @param name the name that failed
* @return a new NameError
*/
public RaiseException newNameError(String message, String name) {
return newNameError(message, name, null);
}

/**
* Construct a NameError with an optional originating exception and a pre-formatted message.
*
* This is the same as calling {@link #newNameError(String, String, Throwable, boolean)} with a null
* originating exception and false for verbose-mode logging.
*
* @param message a formatted string message for the error
* @param name the name that failed
* @param origException the original exception, or null if none
* @return a new NameError
*/
public RaiseException newNameError(String message, String name, Throwable origException) {
return newNameError(message, name, origException, false);
}

/**
* Construct a NoMethodError that formats its message with an sprintf format string.
*
* This works like {@link #newNameError(String, IRubyObject, IRubyObject)} but accepts
* a java.lang.String for name and a RubyArray of the original call arguments.
*
* @see Ruby#newNameError(String, IRubyObject, IRubyObject)
*
* @return a new NoMethodError
*/
public RaiseException newNoMethodError(String message, IRubyObject recv, String name, RubyArray args) {
RubySymbol nameStr = newSymbol(name);
IRubyObject msg = new RubyNameError.RubyNameErrorMessage(this, message, recv, nameStr);
RubyException err = RubyNoMethodError.newNoMethodError(getNoMethodError(), msg, nameStr, args);

return new RaiseException(err);
}

/**
* Construct a NoMethodError that formats its message with an sprintf format string.
*
* This is the same as {@link #newNoMethodError(String, IRubyObject, String, RubyArray)} but without
* capturing the receiver.
*
* @return a new NoMethodError
*/
public RaiseException newNoMethodError(String message, String name, IRubyObject args) {
return new RaiseException(new RubyNoMethodError(this, getNoMethodError(), message, name, args), true);
}

public RaiseException newLocalJumpError(RubyLocalJumpError.Reason reason, IRubyObject exitValue, String message) {
return new RaiseException(new RubyLocalJumpError(this, getLocalJumpError(), message, reason, exitValue), true);
}
@@ -5031,6 +5101,13 @@ public void checkSafeString(IRubyObject object) {
public void secure(int level) {
}

@Deprecated
public RaiseException newNameErrorObject(String message, IRubyObject name) {
RubyException error = new RubyNameError(this, getNameError(), message, name);

return new RaiseException(error, false);
}

// Parser stats methods
private void addLoadParseToStats() {
if (parserStats != null) parserStats.addLoadParse();
18 changes: 14 additions & 4 deletions core/src/main/java/org/jruby/RubyException.java
Original file line number Diff line number Diff line change
@@ -65,20 +65,19 @@ public class RubyException extends RubyObject {

protected RubyException(Ruby runtime, RubyClass rubyClass) {
super(runtime, rubyClass);
// this.message = null; its an internal constructor for sub-classes
this.cause = RubyBasicObject.UNDEF;
}

public RubyException(Ruby runtime, RubyClass rubyClass, String message) {
super(runtime, rubyClass);

this.message = message == null ? runtime.getNil() : runtime.newString(message);
this.setMessage(message == null ? runtime.getNil() : runtime.newString(message));
this.cause = RubyBasicObject.UNDEF;
}

@JRubyMethod(optional = 2, visibility = PRIVATE)
public IRubyObject initialize(IRubyObject[] args, Block block) {
if ( args.length == 1 ) message = args[0];
if ( args.length == 1 ) setMessage(args[0]);
// cause filled in at RubyKernel#raise ... Exception.new does not fill-in cause!
return this;
}
@@ -273,6 +272,7 @@ public void initBacktrace() {
}

@Override
@SuppressWarnings("deprecated")
public void copySpecialInstanceVariables(IRubyObject clone) {
RubyException exception = (RubyException)clone;
exception.backtraceData = backtraceData;
@@ -360,7 +360,7 @@ public Object unmarshalFrom(Ruby runtime, RubyClass type,
// just use real vars all the time for these?
unmarshalStream.defaultVariablesUnmarshal(exc);

exc.message = (IRubyObject)exc.removeInternalVariable("mesg");
exc.setMessage((IRubyObject)exc.removeInternalVariable("mesg"));
exc.set_backtrace((IRubyObject)exc.removeInternalVariable("bt"));

return exc;
@@ -392,10 +392,20 @@ public static IRubyObject newException(ThreadContext context, RubyClass exceptio
/**
* @return error message if provided or nil
*/
@SuppressWarnings("deprecated")
public IRubyObject getMessage() {
return message == null ? getRuntime().getNil() : message;
}

/**
* Set the message for this NameError.
* @param message the message
*/
@SuppressWarnings("deprecated")
public void setMessage(IRubyObject message) {
this.message = message;
}

public String getMessageAsJavaString() {
final IRubyObject msg = getMessage();
return msg.isNil() ? null : msg.toString();
5 changes: 2 additions & 3 deletions core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
@@ -3301,12 +3301,11 @@ public IRubyObject const_missing(ThreadContext context, IRubyObject rubyName, Bl
String longName;

if (this != runtime.getObject()) {
longName = getName() + "::" + shortName;
throw runtime.newNameError("uninitialized constant %2$s::%1$s", this, rubyName);
} else {
longName = shortName;
throw runtime.newNameError("uninitialized constant %1$s", this, rubyName);
}

throw runtime.newNameError("uninitialized constant " + longName, this, rubyName);
}

public RubyArray constants(ThreadContext context) {
16 changes: 13 additions & 3 deletions core/src/main/java/org/jruby/RubyNameError.java
Original file line number Diff line number Diff line change
@@ -98,6 +98,8 @@ public IRubyObject to_str(ThreadContext context) {
return context.nil;
} else {
String description = null;
String separator;
String className = null;
boolean singleton = false;

if (object.isNil()) {
@@ -121,11 +123,19 @@ public IRubyObject to_str(ThreadContext context) {
}

if (!singleton) {
description = description + ':' + object.getMetaClass().getRealClass().getName();
separator = ":";
className = object.getMetaClass().getRealClass().getName();
} else {
className = separator = "";
}
//IRubyObject[] args = new IRubyObject[] { name, runtime.newString(description) };

RubyArray arr = runtime.newArray(name, runtime.newString(description));
RubyArray arr =
runtime.newArray(
name,
runtime.newString(description),
runtime.newString(separator),
runtime.newString(className));

ByteList msgBytes = new ByteList(this.message.length() + description.length() + name.toString().length());
Sprintf.sprintf(msgBytes, this.message, arr);