See src/org/jruby/RubyEnumerable.java
.
@JRubyMethod(name = {"map"}, frame = true, compat = CompatVersion.RUBY1_9)
public static IRubyObject map19(ThreadContext context, IRubyObject self, final Block block) {
return collectCommon19(context, self, block, "map");
}
This looks like defining the map19
method with declaring it's the map
method in Ruby, particularly in 1.9
mode.
For some reason this is internally collectCommon19()
not mapCommon19()
.
private static IRubyObject collectCommon19(ThreadContext context, IRubyObject self, final Block block, String methodName) {
final Ruby runtime = context.getRuntime();
if (block.isGiven()) {
final RubyArray result = runtime.newArray();
callEach19(runtime, context, self, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
IRubyObject larg = checkArgs(runtime, largs);
IRubyObject value = block.yield(ctx, larg);
synchronized (result) {
result.append(value);
}
return runtime.getNil();
}
});
return result;
} else {
return enumeratorize(runtime, self, methodName);
}
}
This is the definition of collectCommon19
. Focus on the then
clause of the main if
condition block.
It's basically calling callEach19()
with an instance of BlockCallback, redefining call()
. This looks like block-passing style in Ruby.
Focus also on the line just before the callEach19()
. The variable result
looks like an empty Ruby array for storing values in map
process. The definition of the method newArray()
is the following.
public RubyArray newArray() {
return RubyArray.newArray(this);
}
OK. How about RubyArray.newArray()
.
/** rb_ary_new
*
*/
public static final RubyArray newArray(final Ruby runtime) {
return newArray(runtime, ARRAY_DEFAULT_SIZE);
}
Ok, next. Note that the constant ARRAY_DEFAULT_SIZE
is an int value.
public static final RubyArray newArray(final Ruby runtime, final int len) {
RubyArray array = new RubyArray(runtime, len);
RuntimeHelpers.fillNil(array.values, 0, array.values.length, runtime);
return array;
}
Looks like [0, ..., 0]
with size ARRAY_DEFAULT_SIZE. So you may wonder is it OK to define a longer array if the receiver of map
has longer size than ARRAY_DEFAULT_SIZE
? I also wonder.
No comments:
Post a Comment