I've created some kind of 'script ecosystem', in which there is one in particular that I would like to be able to share certain variables with the others scripts, but as read-only.
Since Script scoped variables are only accessible by the script itself, I've chosen to store them as DOpus vars.
But the problem I see with that approach is that any script could delete such variables, even accidentally (since you can use wildcards to refer to the var names).
So to the question, what would be the best approach to share variables between scripts, but have them be read-only to others?
I can't remember if include scripts can manage script variables.
If they do, you could have an include script managing these variables and offering functions to get/set those variables.
You could even try to 'secure' the setters with a caller script parameter.
EDIT: After a few tests, as I kinda feared, this will not work. Script.vars can be used in include scripts but they will be interpreted at runtime as the Script.vars of the script that includes it. So this will not be an efficient way to share between scripts.
So far, I can't see a way to protect the variables other than not having them global, but in that case, they can't be shared by the standard way of functionning of vars.
On first approach, I can not think of anything else than reverting to a file (could be handled by an include script that would centraly manage this, and can be as simple as a JSON file that stores an object with the vars names/values ... with a little work to do to transform to/from file the DOpus collections. On that point, I already did some things like that in CommonLogger to store a JSON object in a global var).
Yes, the script I'm talking about does this very often. It's basically a script that allows you (in a very conveniently way) define custom properties. It also allows you to get/set said properties. And you can save them as ADS or in other locations, when convenient. So they work even on FTP, network files, even MTP!
On the other hand, I have other scripts (some old versions are posted on the forum, e.g. ColumnsViewer, MetaWizard), which can get the custom properties, to display/set them, as if they were editable properties of Opus itself. It's really very cool.
I've tried a bit with this, but at least it works for me here, why do you say it doesn't for you?
Basically, it's an include script with a list of allowed setters (anyone can get the values) and some functions to get/set the shared variables.
And now, these variables technically no longer belong to the original script owner, but to the include script. And what has changed is that to read/set them you must use the include script proper functions, instead of the conventional way. It's a bit 'over the top' thing but it's fine with me.
I think a function in the include script to check if a certain shared variable exists, just like the conventional way, would be nice.
// ProtectedVarsMgr
// (c) 2025 SALESSIO
// This is an include file script for Directory Opus.
// See https://www.gpsoft.com.au/endpoints/redirect.php?page=scripts for development information.
// Called by Directory Opus to initialize the include file script
function OnInitIncludeFile(initData)
{
initData.name = "ProtectedVarsMgr";
initData.version = "1.0";
initData.copyright = "(c) 2025 SALESSIO";
// initData.url = "https://resource.dopus.com/c/buttons-scripts/16";
initData.desc = "";
initData.min_version = "13.0";
initData.shared = true;
}
function PVM_InitVars() {
DOpus.Output("PVM_InitVars");
DOpus.Output("Vars size before init = " + Script.vars.count);
var allVars = Script.vars;
allVars.Set("PVM_var_A", true);
allVars.Set("PVM_var_B", "my B var value");
DOpus.Output("Vars size = " + Script.vars.count);
DOpus.Output("PVM_var_A = " + Script.vars.Get("PVM_var_A"));
DOpus.Output("PVM_var_B = " + Script.vars.Get("PVM_var_B"));
}
function PVM_GetValue(varName, target) {
DOpus.Output("Vars size = " + Script.vars.count);
if (!Script.vars.Exists(varName))
return false;
target = Script.vars.Get(varName);
DOpus.Output("Returning = " + target);
return true;
}
function PVM_SetValue(varName, newValue) {
DOpus.Output("Vars size = " + Script.vars.count);
if (!Script.vars.Exists(varName))
return false;
Script.vars.Set(varName, newValue);
return true;
}
function result() {
this.status;
this.result;
}
Script 1
Has 2 commands : One to call the InitVars, and one to retrieve and then change the value of one of the vars.
// Test_PVM_1
// (c) 2025 SALESSIO
// This is a script for Directory Opus.
// See https://www.gpsoft.com.au/endpoints/redirect.php?page=scripts for development information.
// Called by Directory Opus to initialize the script
function OnInit(initData)
{
initData.name = "Test_PVM_1";
initData.version = "1.0";
initData.copyright = "(c) 2025 SALESSIO";
// initData.url = "https://resource.dopus.com/c/buttons-scripts/16";
initData.desc = "";
initData.default_enable = true;
initData.min_version = "13.0";
var cmd = initData.AddCommand();
cmd.name = "TestPVM_InitVars";
cmd.method = "OnTestPVM_InitVars";
cmd.desc = "";
cmd.label = "TestPVM_InitVars";
cmd.template = "";
cmd.hide = false;
cmd.icon = "script";
var cmd = initData.AddCommand();
cmd.name = "TestPVM_1";
cmd.method = "OnTestPVM_1";
cmd.desc = "";
cmd.label = "TestPVM_1";
cmd.template = "";
cmd.hide = false;
cmd.icon = "script";
}
function OnTestPVM_InitVars(scriptCmdData)
{
DOpus.Output("Init PVM vars");
PVM_InitVars();
}
function OnTestPVM_1(scriptCmdData)
{
DOpus.Output("OnTestPVM_1");
var myBool;
if (PVM_GetValue("PVM_var_A", myBool))
DOpus.Output("var_A returned : " + myBool);
else
DOpus.Output("Error on retrieving var_A");
if (PVM_SetValue("PVM_var_A", !myBool))
DOpus.Output("var_A set to : " + !myBool);
else
DOpus.Output("Error on setting var_A");
}
Script 2
Has 1 command to retrieve the value of the same var thar script 1 can alter.
// Test_PVM_2
// (c) 2025 SALESSIO
// This is a script for Directory Opus.
// See https://www.gpsoft.com.au/endpoints/redirect.php?page=scripts for development information.
// Called by Directory Opus to initialize the script
function OnInit(initData)
{
initData.name = "Test_PVM_2";
initData.version = "1.0";
initData.copyright = "(c) 2025 SALESSIO";
// initData.url = "https://resource.dopus.com/c/buttons-scripts/16";
initData.desc = "";
initData.default_enable = true;
initData.min_version = "13.0";
}
// Called to add commands to Opus
function OnAddCommands(addCmdData)
{
var cmd = addCmdData.AddCommand();
cmd.name = "Test_PVM_2";
cmd.method = "OnTest_PVM_2";
cmd.desc = "";
cmd.label = "Test_PVM_2";
cmd.template = "";
cmd.hide = false;
cmd.icon = "script";
}
// Implement the Test_PVM_2 command
function OnTest_PVM_2(scriptCmdData)
{
DOpus.Output("OnTestPVM_2");
var myBool;
if (PVM_GetValue("PVM_var_A",myBool))
DOpus.Output("var_A returned : " + myBool);
else
DOpus.Output("Error on retrieving var_A");
}
What's not working?
Apart from the var value assignement which is not working but that's unrelated, when calling in order:
Script 1: InitVars ==> OK. (Script.vars.count = 0 when entering and Script.vars.count = 2 when exiting)
Script 1: Get & Change variable A ==> (Script.vars.count = 2 when entering and exiting)
Script 2: Get variable A : it does not exists. Script.vars.count = 0 when entering.
My understanding is that, calling Script.vars in a function that is inside an include file is interpreted at runtime as if you'd have called it from the script you included that file into - just like if the included file code had been added to the file you included it into.
Ah, yes—I got too excited and just tried it with one script. It seems that the variables from the included scripts remain separate for each script who call it.
Yep.
In the end, it looks like include script really means include :).
In a way, this makes sense: if the include script provides mechanics that require to be specific to each other script that includes it, then having the Script.vars attached to the using script is necessary.
Maybe it could be a feature request to have another type of Vars (complementing Lister, Tab, Opus, Script): IncludeScript.Vars which can hold script variables that are used within an include script but that are shared by all the scripts including it.
Since I don't know the way these include script are managed in relation to the using scripts, this could be not so easy to implement on Opus side. @Jon / @Leo: any thought on this ?
EDIT: Or a boolean property on the var itself (shared?) but it wouldn't make much sense in the other vars contexts (Lister, Tab, Global, ...).