Following execution of a internal script command via eval Run(), variables defined within that script, regardless of scope (global, list, tab, or local) are unavailable for retrieval using the Val() function. Obviously the variables are available when the button is run a second time except for a local variable.
Discovering this after I create the thread it appears the eval Run() function doesn't work with @evalalways modifier. I was hoping I could set tooltips etc with the values returned from a internal script command. Unless support is added to allow Run() to work with @evalalways you can disregard this thread.
Initial test attempt with @evalalways:=Run() were unsuccessful due to time limitations, I had to get off the PC. I copied and pasted a command that didn't give me feedback without realizing. This is how I came to the above conclusion. Now that I have more time subsequent testing has confirmed its proper operation. So if only I could access those variables, in the same execution thread.
Something like this:
@evalalways:=Run("VarTest")
// do something with value returned from VarTest such as include it in a button tooltip, etc
@evalalways:=Val("$var_test")
I would avoid running external commands or scripts via @eval: or @evalalways: as it could cause performance problems. Such things may be triggered several times a second if the toolbar needs updating.
From what I understand ONE of the reasons the evaluator was added is because it's faster than a script in certain aspects (a faster alternative to script column for example). I was going to request being able to pass information from a script to the evaluator months ago but I didn't because I thought the performance issue would be brought up just as you mentioned above. But wouldn't it depend on how heavy or light the script is? Surely some light script wouldn't cause too much of a performance hit. But now the eval Run() command was just added that can run an internal script command. The only part lacking is the transfer of the variables from the script function to the evaluator. Whether or not the performance would be affected is up to the user to accept or decline to include with @evalalways based on the script.
I just tested a button description with =Run("internal_script_cmd") and it appears to only run when the tooltip pops up. The command I tested with is an actual function I would use with @evalalways and I'm not noticing any performace issues not even a longer delay for the tooltip to appear. It seems to be ok with a tooltip but I could see a lot more updating with a label or enabling/disabling a button and thus the performance hit.
Not my call, but if you include a real-life example, it might help to others to give you some ideas.
As far as I know, a script cannot return values even if you call it from another script, but you can use variables in all available scopes for that. And scripts can react to events too, something that Evaluator lacks.
An example is here it's just spread throughout the posts and even another thread (as pointed out above). I will put it all together here, something I should've done from the start.
That's what the example uses, all the scopes to test each but are not accessible from eval.
Script
function OnInit(init)
{
init.name = "Script var to eval via Run() test";
init.default_enable = true;
var cmd = init.AddCommand();
cmd.name = "VarTest";
cmd.label = "VarTest";
cmd.method = "VarTest";
return false;
}
function VarTest(data)
{
DOpus.vars("var_test") = "GlobalVar";
DOpus.Listers(0).vars("var_test") = "ListerVar";
data.Func.sourcetab.vars("var_test") = "SourceVar";
data.Func.Command.vars("var_test") = "CommandVar";
}
Button1
=Run("VarTest")
// Variables not accessible from evalulator (on first execution)
// If you see the variables in the output pane try clearing them with Button2 first
=Output(Val("$glob:var_test"))
=Output(Val("$lst:var_test"))
=Output(Val("$src:var_test"))
=Output(Val("$var_test"))
Button2
// Remove vars set from script
@set $glob:var_test
@set $lst:var_test
@set $src:var_test
I was asking more for an actual user case application, not something to demonstrate that you can't call the new Evaluator functions using @evalalways.
Anyway, it seems your application would be doing things like changing labels, enabling and disabling buttons, etc. Fwiw, all of that and more can already be done via scripting with dynamic buttons.
You can put Evaluator code directly into a button's Tooltip field (starting with = to indicate it's code not a normal string), which should avoid the need to use @eval or @evalalways and it running more often than needed.
An example of passing back information from a script to evaluator. A small helper function to ensure only movie files are renamed even if non-movie files happen to be included in the selection. Useful if you have several buttons that rename movie files (or any other group). Also modifying the group in File Types dialog will reflect the changes in all the buttons.
I hope there isn't a way to already do this with some eval function I overlooked, otherwise this script was for nothing. If there is let me know!
Script
function OnInit(init)
{
var cmd = init.AddCommand();
cmd.name = "FileTypeGrp";
cmd.label = "FileTypeGrp";
cmd.method = "FileTypeGrp";
cmd.template = "GROUP/R";
cmd.desc = "Get string of a file group ext1|ext2|ext3";
}
function FileTypeGrp(data)
{
var exts = "";
var delim = "|";
if (data.func.args.group)
{
var grp = DOpus.FiletypeGroups.GetGroup(data.func.args.group);
if (grp)
{
for (var i = 0 ;i < grp.count; i++)
{
if (i == grp.count -1)
delim = "";
exts += String(grp(i)).substring(1) + delim;
}
data.func.command.vars("file_group") = exts;
}
}
}