From bcc71ef194690c767396f5d0b3ef6c784efeca1c Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 20 Jun 2024 02:27:42 -0500 Subject: [PATCH] Eliminate remaining uses of getInstanceVariableList --- .../main/java/org/jruby/BasicObjectStub.java | 18 +++++++++++------- .../main/java/org/jruby/RubyBasicObject.java | 15 ++++++++++----- .../runtime/builtin/InstanceVariables.java | 5 +++++ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/org/jruby/BasicObjectStub.java b/core/src/main/java/org/jruby/BasicObjectStub.java index ba16732c24c..609e4cf0573 100644 --- a/core/src/main/java/org/jruby/BasicObjectStub.java +++ b/core/src/main/java/org/jruby/BasicObjectStub.java @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.List; +import java.util.function.BiConsumer; import org.jruby.runtime.Helpers; import org.jruby.runtime.Block; @@ -259,13 +260,16 @@ public static IRubyObject inspect(IRubyObject self) { */ private static StringBuilder inspectObj(IRubyObject self, StringBuilder part) { ThreadContext context = getRuntime(self).getCurrentContext(); - String sep = ""; - - for (Variable ivar : getInstanceVariables(self).getInstanceVariableList()) { - part.append(sep).append(' ').append(ivar.getName()).append('='); - part.append(invokedynamic(context, ivar.getValue(), INSPECT)); - sep = ","; - } + getInstanceVariables(self).forEachInstanceVariable(new BiConsumer<>() { + String sep = ""; + + @Override + public void accept(String name, IRubyObject value) { + part.append(sep).append(' ').append(name).append('='); + part.append(invokedynamic(context, value, INSPECT)); + sep = ","; + } + }); part.append('>'); return part; } diff --git a/core/src/main/java/org/jruby/RubyBasicObject.java b/core/src/main/java/org/jruby/RubyBasicObject.java index c903227a6ae..386a37e2bf5 100644 --- a/core/src/main/java/org/jruby/RubyBasicObject.java +++ b/core/src/main/java/org/jruby/RubyBasicObject.java @@ -50,6 +50,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiConsumer; import org.jruby.anno.JRubyMethod; import org.jruby.common.IRubyWarnings.ID; @@ -1579,11 +1580,7 @@ public List getInstanceVariableNameList() { */ @Override public void copyInstanceVariablesInto(final InstanceVariables other) { - for (Variable var : getInstanceVariableList()) { - synchronized (this) { - other.setInstanceVariable(var.getName(), var.getValue()); - } - } + forEachInstanceVariable(other::setInstanceVariable); } /** @@ -1602,6 +1599,14 @@ public final void ensureInstanceVariablesSettable() { } } + public void forEachInstanceVariable(BiConsumer accessor) { + metaClass.getVariableAccessorsForRead().forEach((name, var) -> { + final Object value = var.get(this); + if (!(value instanceof IRubyObject rubyObject) || !IdUtil.isInstanceVariable(name)) return; + accessor.accept(name, rubyObject); + }); + } + private void raiseFrozenError() throws RaiseException { if (this instanceof RubyModule) { throw getRuntime().newFrozenError("class/module ", this); diff --git a/core/src/main/java/org/jruby/runtime/builtin/InstanceVariables.java b/core/src/main/java/org/jruby/runtime/builtin/InstanceVariables.java index 98da02e5028..f51e355c744 100644 --- a/core/src/main/java/org/jruby/runtime/builtin/InstanceVariables.java +++ b/core/src/main/java/org/jruby/runtime/builtin/InstanceVariables.java @@ -6,6 +6,7 @@ package org.jruby.runtime.builtin; import java.util.List; +import java.util.function.BiConsumer; /** * Interface that represents the instance variable aspect of Ruby @@ -74,4 +75,8 @@ public interface InstanceVariables { * Copies all instance variables from the given object into the receiver */ void copyInstanceVariablesInto(InstanceVariables other); + + default void forEachInstanceVariable(BiConsumer accessor) { + getInstanceVariableList().forEach((var) -> accessor.accept(var.getName(), var.getValue())); + } }