diff --git a/eo-runtime/src/main/java/org/eolang/Data.java b/eo-runtime/src/main/java/org/eolang/Data.java index 7e167baf8a..21c5719429 100644 --- a/eo-runtime/src/main/java/org/eolang/Data.java +++ b/eo-runtime/src/main/java/org/eolang/Data.java @@ -48,86 +48,6 @@ public interface Data { */ T take(); - /** - * Data being returned only once, from encapsulated object. - * - * @param The type of data - * @since 0.1 - */ - final class Once implements Data { - - /** - * Data. - */ - private final Data src; - - /** - * Reference. - */ - private final AtomicReference ref; - - /** - * Blank supplier. - */ - private final Supplier blank; - - /** - * Ctor. - * @param data Data to return - * @param txt Missing data text - */ - public Once(final Data data, final Supplier txt) { - this.src = data; - this.ref = new AtomicReference<>(); - this.blank = txt; - } - - @Override - public int hashCode() { - return this.take().hashCode(); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - return this.take().equals(((Once) obj).take()); - } - - @Override - public String toString() { - final T data = this.ref.get(); - String txt = this.blank.get(); - if (txt.isEmpty()) { - txt = this.take().toString(); - } else if (data != null) { - txt = data.toString(); - } - return txt; - } - - @Override - public T take() { - synchronized (this.ref) { - return this.ref.updateAndGet( - t -> { - final T result; - if (t == null) { - result = Once.this.src.take(); - } else { - result = t; - } - return result; - } - ); - } - } - } - /** * Makes a {@link Phi} out of a Java object, like {@link String} or {@link Integer}. * diff --git a/eo-runtime/src/main/java/org/eolang/PhOnce.java b/eo-runtime/src/main/java/org/eolang/PhOnce.java index 76f3923718..235c94921f 100644 --- a/eo-runtime/src/main/java/org/eolang/PhOnce.java +++ b/eo-runtime/src/main/java/org/eolang/PhOnce.java @@ -24,6 +24,7 @@ package org.eolang; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; /** @@ -37,82 +38,105 @@ class PhOnce implements Phi { /** * The object fetched. */ - private final Data object; + private final Supplier object; /** - * The expression provider. + * As string representation. */ - private final Supplier exp; + private final Supplier string; + + /** + * As φ term representation. + */ + private final Supplier term; + + /** + * Reference. + */ + private final AtomicReference ref; /** * Ctor. * - * @param data The object - * @param blank The string value - * @param expr The expression + * @param obj The object + * @param str The "as string" value + * @param trm The "as φ term" value */ - PhOnce(final Data data, final Supplier blank, final Supplier expr) { - this.object = new Data.Once<>(data, blank); - this.exp = expr; + PhOnce(final Supplier obj, final Supplier str, final Supplier trm) { + this.ref = new AtomicReference<>(null); + this.object = () -> { + synchronized (this.ref) { + if (this.ref.get() == null) { + this.ref.set(obj.get()); + } + return this.ref.get(); + } + }; + this.string = str; + this.term = trm; } @Override public boolean equals(final Object obj) { - return this.object.take().equals(obj); + return this.object.get().equals(obj); } @Override public int hashCode() { - return this.object.take().hashCode(); + return this.object.get().hashCode(); } @Override public final String toString() { - return this.object.toString(); + return this.string.get(); } @Override public final String φTerm() { - return this.exp.get(); + return this.term.get(); } @Override public Phi copy() { - return this.object.take().copy(); + return new PhOnce( + () -> this.object.get().copy(), + () -> String.format("%s'", this.string), + this.term + ); } @Override public Phi take(final int pos) { - return this.object.take().take(pos); + return this.object.get().take(pos); } @Override public Phi take(final String name) { - return this.object.take().take(name); + return this.object.get().take(name); } @Override public Phi take(final String name, final Phi rho) { - return this.object.take().take(name, rho); + return this.object.get().take(name, rho); } @Override public void put(final int pos, final Phi obj) { - this.object.take().put(pos, obj); + this.object.get().put(pos, obj); } @Override public void put(final String name, final Phi obj) { - this.object.take().put(name, obj); + this.object.get().put(name, obj); } @Override public String locator() { - return this.object.take().locator(); + return this.object.get().locator(); } @Override public String forma() { - return this.object.take().forma(); + return this.object.get().forma(); } } diff --git a/eo-runtime/src/test/eo/org/eolang/switch-tests.eo b/eo-runtime/src/test/eo/org/eolang/switch-tests.eo index 15094a1f9f..8036571bbf 100644 --- a/eo-runtime/src/test/eo/org/eolang/switch-tests.eo +++ b/eo-runtime/src/test/eo/org/eolang/switch-tests.eo @@ -27,9 +27,6 @@ +version 0.0.0 # Test. -# @todo #2931:30min Enable the test switch-with-all-false-cases. For some reason it fails with -# "Given index is out of tuple bounds". It seems comparison inside "switch" does not work properly -# Need to find out what's going on and enable the test. [] > switch-simple-case eq. > @ switch @@ -77,17 +74,14 @@ # Test. [] > switch-with-all-false-cases - eq. > res - switch + switch > @ + * * - * - FALSE - "FALSE1" - * - FALSE - "FALSE2" - TRUE - TRUE > @ + FALSE + "FALSE1" + * + FALSE + "FALSE2" # Test. [] > switch-case-with-error