cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar

Best practice for preventing namespace pollution/cross-talk when calling Functions in an included file

There are several threads on this topic already, as well as a section in the Scripting Guide, but none really answer my question.

 

I have two files, Main.jsl and Function.jsl, and I include the latter file in the former. There is a Function defined in Function.jsl that I wish to call inside of a For loop in Main.jsl. The problem I had is that the called Function also uses a For loop, and both the For loops in Main.jsl and the Function in Function.jsl use i as a counting variable, hence this resulted in namespace pollution. 

 

I have tried a bunch of combinations with using Names Default Here(1) at different locations in either files, using the << New Context argument in Include(), and even defining the Function name as a global variable using :: in order to try to solve this issue. However, the problem was always that either 1) I was able to call the Function in Function.jsl from Main.jsl, but there would be namespace pollution, or 2) I would not be able to call the Function in Function.jsl from Main.jsl because the Function was defined in a namespace or scope that I did not know how to access. 

 

My current workaround is to explicitly define i and the contents of the entire Function inside of a Local(), and defining the Function itself as a global variable as such:

 

Main.jsl

Include("Function.jsl", << New Context);

Names Default To Here(1);

for(i = 1, i <= 10, i++,
    returns = ::function(arguments);
);

Function.jsl

::function = Function({arguments},
    Local({i},
        for(i = 1, i <= 20, i++,
            Do Something;
        );
Return(returns); ); );

My question is: Is this really the correct way to go about it? For example, I think it would be better if I could assign a namespace to Function.jsl, and then use this to call the Function instead of messing with global variables, like returns = ns_function:function(arguments);. And ideally this would then also prevent the namespace pollution because the i in Main.jsl is in the namespace Here, while the i in Function.jsl is in the namespace ns_function. But I do not know how/if this is possible. 

 

Using JMP Pro 16.2 (570548) on Windows 10 Enterprise 64-bit.

1 ACCEPTED SOLUTION

Accepted Solutions
jthi
Super User

Re: Best practice for preventing namespace pollution/cross-talk when calling Functions in an included file

In this case you could also function({arguments}, {Default Local}) to declare that all unscoped variables used in the function are local to the function (this is what I do 99% of the time).

//main.jsl
Names Default To Here(1);

Include("test.jsl");

For(i = 1, i <= 5, i++,
testparam = i;
	return = test();
	show(i);
	show(return);
);

 

 

 

 

 

//test.jsl
Names Default To Here(1);

test = function({}, {Default Local},
	For(i = 1, i <= 20, i++,
		show(i);
	);
	show(testparam);
	return("done");
)

Function({arguments}, <{local variables}>, <Return(<expr>)>, script) 

 

-Jarmo

View solution in original post

2 REPLIES 2
jthi
Super User

Re: Best practice for preventing namespace pollution/cross-talk when calling Functions in an included file

In this case you could also function({arguments}, {Default Local}) to declare that all unscoped variables used in the function are local to the function (this is what I do 99% of the time).

//main.jsl
Names Default To Here(1);

Include("test.jsl");

For(i = 1, i <= 5, i++,
testparam = i;
	return = test();
	show(i);
	show(return);
);

 

 

 

 

 

//test.jsl
Names Default To Here(1);

test = function({}, {Default Local},
	For(i = 1, i <= 20, i++,
		show(i);
	);
	show(testparam);
	return("done");
)

Function({arguments}, <{local variables}>, <Return(<expr>)>, script) 

 

-Jarmo

Re: Best practice for preventing namespace pollution/cross-talk when calling Functions in an included file

Thank you! With the {Default Local} flag this works exactly as I wanted it to.