diff --git a/src/main/java/org/scijava/parsington/eval/AbstractEvaluator.java b/src/main/java/org/scijava/parsington/eval/AbstractEvaluator.java index 82502ba..4be9e8e 100644 --- a/src/main/java/org/scijava/parsington/eval/AbstractEvaluator.java +++ b/src/main/java/org/scijava/parsington/eval/AbstractEvaluator.java @@ -30,7 +30,6 @@ package org.scijava.parsington.eval; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -73,6 +72,11 @@ public void setStrict(final boolean strict) { this.strict = strict; } + @Override + public Map vars() { + return vars; + } + @Override public Object get(final String name) { // NB: Here, we look up the key twice: once with containsKey, then @@ -89,29 +93,4 @@ public Object get(final String name) { return new Unresolved(name); } - @Override - public Map getAll() { - return Collections.unmodifiableMap(vars); - } - - @Override - public void set(final String name, final Object value) { - vars.put(name, value); - } - - @Override - public void setAll(final Map map) { - vars.putAll(map); - } - - @Override - public Object remove(final String name) { - return vars.remove(name); - } - - @Override - public void clear() { - vars.clear(); - } - } diff --git a/src/main/java/org/scijava/parsington/eval/Evaluator.java b/src/main/java/org/scijava/parsington/eval/Evaluator.java index 1be84d2..9395dd5 100644 --- a/src/main/java/org/scijava/parsington/eval/Evaluator.java +++ b/src/main/java/org/scijava/parsington/eval/Evaluator.java @@ -112,6 +112,17 @@ public interface Evaluator { */ Object evaluate(SyntaxTree syntaxTree); + /** + * Gets all variables as a mutable {@link Map}. Not thread-safe. + *

+ * This map is a view, not a copy—i.e., changes to this map alter the + * evaluator's actual variable values. + *

+ * + * @return The map from variable names to variable values. + */ + Map vars(); + /** * Gets the value of a token. For variables, returns the value of the * variable, throwing an exception if the variable is not set. For literals, @@ -153,7 +164,9 @@ default Variable var(final Object token) { * @param name The name of the variable whose value you want to set. * @param value The value to assign to the variable. */ - void set(String name, Object value); + default void set(String name, Object value) { + vars().put(name, value); + } /** * Gets the value of a variable. @@ -167,13 +180,6 @@ default Object get(final Variable v) { return get(v.getToken()); } - /** - * Gets a map of all variable names and values. - * - * @return A map from variable names to variable values. - */ - Map getAll(); - /** * Sets the value of a variable. * @@ -189,7 +195,9 @@ default void set(final Variable v, final Object value) { * * @param map A map from variable names to variable values. */ - void setAll(Map map); + default void setAll(Map map) { + vars().putAll(map); + } /** * Removes the named variable. @@ -198,12 +206,15 @@ default void set(final Variable v, final Object value) { * @return The previous variables value associated with name, * or null if the name did not exist. */ - Object remove(String name); + default Object remove(String name) { + return vars().remove(name); + } /** * Clears all the variables. - * */ - void clear(); + default void clear() { + vars().clear(); + } } diff --git a/src/test/java/org/scijava/parsington/eval/AbstractEvaluatorTest.java b/src/test/java/org/scijava/parsington/eval/AbstractEvaluatorTest.java index 62d5fc9..5b66364 100644 --- a/src/test/java/org/scijava/parsington/eval/AbstractEvaluatorTest.java +++ b/src/test/java/org/scijava/parsington/eval/AbstractEvaluatorTest.java @@ -83,17 +83,18 @@ public void testClear() { final Evaluator e = createEvaluator(); e.set("a", 1); e.set("b", 2); + assertEquals(2, e.vars().size()); e.clear(); - assertEquals(new HashMap<>(), e.getAll()); + assertEquals(0, e.vars().size()); assertThrows(IllegalArgumentException.class, () -> e.get("a")); assertThrows(IllegalArgumentException.class, () -> e.get("b")); } - /** Tests {@link Evaluator#getAll()} and {@link Evaluator#setAll(Map)}. */ + /** Tests {@link Evaluator#vars()} and {@link Evaluator#setAll(Map)}. */ @Test - public void testGetAllSetAll() { + public void testVarsSetAll() { final Evaluator e = createEvaluator(); - assertEquals(new HashMap<>(), e.getAll()); + assertEquals(new HashMap<>(), e.vars()); final Map vars = new HashMap<>(); vars.put("a", 1); @@ -101,7 +102,7 @@ public void testGetAllSetAll() { vars.put("c", 3.0); e.setAll(vars); - assertEquals(vars, e.getAll()); + assertEquals(vars, e.vars()); // Verify individual get still works after setAll. assertEquals(1, e.get("a")); @@ -110,9 +111,9 @@ public void testGetAllSetAll() { // Verify variables created at evaluation are accessible and correct. e.evaluate("d=a+c"); - assertTrue(e.getAll().containsKey("d")); + assertTrue(e.vars().containsKey("d")); final Object dVal = e.get("d"); assertEquals(4.0, dVal); - assertEquals(dVal, e.getAll().get("d")); + assertEquals(dVal, e.vars().get("d")); } }