Skip to content

Commit

Permalink
Move Hash#to_proc to Ruby.
Browse files Browse the repository at this point in the history
The old impl was a custom Block implementation with a null block
and binding, which caused many issues when methods like
instance_exec attempted to break it into consitutent pieces and
use them separately.

This may help #4037.
headius committed Aug 10, 2016
1 parent 00138bf commit ba467df
Showing 3 changed files with 11 additions and 105 deletions.
108 changes: 4 additions & 104 deletions core/src/main/java/org/jruby/RubyHash.java
Original file line number Diff line number Diff line change
@@ -44,16 +44,20 @@
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.exceptions.RaiseException;
import org.jruby.javasupport.JavaUtil;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Binding;
import org.jruby.runtime.Block;
import org.jruby.runtime.BlockBody;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.Constants;
import org.jruby.runtime.Frame;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.JavaSites.HashSites;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.Signature;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.marshal.MarshalStream;
import org.jruby.runtime.marshal.UnmarshalStream;
@@ -876,110 +880,6 @@ public void visit(ThreadContext context, RubyHash self, IRubyObject key, IRubyOb
}
};

@JRubyMethod(name = "to_proc")
public RubyProc to_proc(ThreadContext context) {

This comment has been minimized.

Copy link
@chrisseaton

chrisseaton Aug 11, 2016

Contributor

This is still used from other Java code though - e.g. MapJavaProxy 451.

final Ruby runtime = context.runtime;
return new RubyProc(runtime, runtime.getProc(), new HashBlock(), null, -1);
}

private class HashBlock extends Block {

HashBlock() {
super(BlockBody.NULL_BODY);
this.type = Block.Type.PROC;
}

private void checkArity(ThreadContext context, IRubyObject... args) {
// acts like a Proc but validate args like a lambda :
Signature.ONE_ARGUMENT.checkArity(context.runtime, args);
}

@Override
public Signature getSignature() {
return Signature.ONE_ARGUMENT;
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject[] args) {
checkArity(context, args);
return op_aref(context, args[0]);
}
@Override
public IRubyObject call(ThreadContext context, IRubyObject[] args, Block blockArg) {
return call(context, args);
}

@Override
public IRubyObject call(ThreadContext context) {
checkArity(context); // fails
throw new AssertionError();
}
@Override
public IRubyObject call(ThreadContext context, Block blockArg) {
return call(context);
}
@Override
public IRubyObject yieldSpecific(ThreadContext context) {
return call(context);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject arg0) {
return op_aref(context, arg0);
}
@Override
public IRubyObject call(ThreadContext context, IRubyObject arg0, Block blockArg) {
return call(context, arg0);
}
@Override
public IRubyObject yieldSpecific(ThreadContext context, IRubyObject arg0) {
return call(context, arg0);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject arg0, IRubyObject arg1) {
checkArity(context, arg0, arg1); // fails
throw new AssertionError();
}
@Override
public IRubyObject call(ThreadContext context, IRubyObject arg0, IRubyObject arg1, Block blockArg) {
return call(context, arg0, arg1);
}
@Override
public IRubyObject yieldSpecific(ThreadContext context, IRubyObject arg0, IRubyObject arg1) {
return call(context, arg0, arg1); // fails
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) {
checkArity(context, arg0, arg1, arg2); // fails
throw new AssertionError();
}
@Override
public IRubyObject call(ThreadContext context, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block blockArg) {
return call(context, arg0, arg1, arg2);
}
@Override
public IRubyObject yieldSpecific(ThreadContext context, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) {
return call(context, arg0, arg1, arg2); // fails
}

@Override
public IRubyObject yield(ThreadContext context, IRubyObject value) {
return op_aref(context, value);
}
@Override
public IRubyObject yieldNonArray(ThreadContext context, IRubyObject value, IRubyObject self) {
return yield(context, value);
}

@Override
public IRubyObject yieldArray(ThreadContext context, IRubyObject value, IRubyObject self) {
throw new UnsupportedOperationException();
}

}

/** rb_hash_to_s & to_s_hash
*
*/
3 changes: 2 additions & 1 deletion core/src/main/ruby/jruby/kernel.rb
Original file line number Diff line number Diff line change
@@ -34,4 +34,5 @@
load 'jruby/kernel/range.rb'
load 'jruby/kernel/load_error.rb'
load 'jruby/kernel/file.rb'
load 'jruby/kernel/basicobject.rb'
load 'jruby/kernel/basicobject.rb'
load 'jruby/kernel/hash.rb'
5 changes: 5 additions & 0 deletions core/src/main/ruby/jruby/kernel/hash.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Hash
def to_proc
->(key) {self[key]}
end
end

0 comments on commit ba467df

Please sign in to comment.