imagej / imagej2

Open scientific N-dimensional image processing :microscope: :sparkler:
https://imagej.net/
BSD 2-Clause "Simplified" License
1.2k stars 337 forks source link

Returning a string from a function call requires converting to string #171

Open AVHon opened 7 years ago

AVHon commented 7 years ago

Given the following ImageJ macro:

function pickFile(){
    return File.openDialog("Pick a file");
}

function notBuggy(){
    return toString(pickFile());
}

function buggy(){
    return pickFile();
}

pickFile();
notBuggy();
buggy();

This will ask you to pick 3 files. The first 2 times work, but the 3rd one fails with:

Numeric return value expected in line 11.
return pickFile( <)> ;

FIJI on ImageJ 1.51p, Java 1.8.0, MacOS 10.12.5

ctrueden commented 7 years ago

@avh-on1 Have you considered using the script parameter syntax? Here is an example macro:

#@File file
print("You chose: " + file)
imagejan commented 7 years ago

To my knowledge, the ImageJ1 macro language only supports numeric and string types. From the documentation:

The ImageJ macro language is "typeless". Variables do not need to be declared and do not have explicit data types. They are automatically initialized when used in an assignment statement. A variable can contain a number, a string or an array.

Trying to assign the return value of pickFile() to a variable results in the same error:

a = pickFile()

So, @avh-on1, use the parameter syntax as suggested by @ctrueden, or switch to any of the other available scripting languages if you want to work with Files and other Java objects.

AVHon commented 7 years ago

I don't mind that "file paths" are actually strings in ImageJ macros. What I do mind is that returning the results of a function call only works if the result is a number. Why can't I return a string?

imagejan commented 7 years ago

Ok, so what actually doesn't work is returning nested function calls if their return value is a string:

function stringValue(){
    return "Test";
}

function nestedStringValue1(){
    a = stringValue();
    return a;
}

function nestedStringValue2(){
    return stringValue(); // doesn't work
}

print (stringValue());
print (nestedStringValue1());
print (nestedStringValue2());

That is a shortcoming of the IJ1 macro language, and @rasband might want to comment on this.

For the time being, I recommend choosing a full-fledged scripting language (such as Javascript, Groovy, Python) anyways. :-)

AVHon commented 7 years ago

@ctrueden, I tried your suggestion of using script parameter syntax in my functions. It doesn't work, hence #173.

imagejan commented 7 years ago

Can you explain why you need this to be nested? Can't you work with the script input parameters being global?

Maybe you can create a topic on the ImageJ forum describing your use case and goals, then we can try to find the best possible solution for you.