ImageJ macro language seems inconsistent in string handling

The ImageJ macro language seems a bit inconsistent in the way it handles strings.

For example, if you try to round a string containing a number then you get an error:

print(round('32.0'));

Returns:

Macro Error: Number or numeric function expected in line 1

However, if you try to round a string containing a number from “List.get()” you get the number back without an error, even though the result is still treated as a string:

newImage("Untitled", "32-bit black", 128, 128, 1);
makeOval(32, 37, 61, 61);
List.setMeasurements;
print(List.get("BX")); //Returns 32.0 - acts like string
print(round(List.get("BX"))); //Returns 32 - acts like Int
print(round(List.get("BX")+1)); //Returns 33 - acts like Int
print(List.get("BX")+1); //Returns 32.01 - acts like string

Returns:

32.0
32
33
32.01

The macro language also does not throw an error if a string is compared to a string, or a string is compared to a number, for example according to ImageJ the following statements are true:

“apple” < “pear”
“32” < 6.4
32 > 6.4

Does anyone have any insights on why the macro language treats strings from List.get() differently, as well as how a string can be compared to a number, or one string can be greater in value than another?

1 Like

Hi @Llamero,

Just some guesses:

  • “apple” < “pear” due to lexicographical order
  • “32” < 6.4 because the first operand determines the type, hence the second is convert to String (again lexicographical order)
  • 32 > 6.4 regular comparison…

Best,
Stefan

2 Likes

Hey Stefan,

Thanks for pointing out that strings can be compared using lexicographical order, that definitely makes sense.

Do you have any ideas on why Strings from the List function are treated differently than explicit Strings?

List.get returns a String, but round() assumes a number and converts string args as seen here:

Jerome.

The logic behind return types of macro functions starts here:

You can avoid these inconsistencies by using getValue() instead of List.get(). For example

  newImage("Untitled", "32-bit black", 128, 128, 1);
  makeOval(32, 37, 61, 61);
  print(getValue("BX")); 
  print(round(getValue("BX")));
  print(round(getValue("BX")+1));
  print(getValue("BX")+1);

outputs

  32
  32
  33
  33

The getValue() function returns a number and List.get() returns a string. You need to be running ImageJ 1.52p or later to use getValue() to retrieve measurement results.

1 Like