Jump to content
Sign in to follow this  
jaynic

Problems with scoping (I think)

Recommended Posts

Hey all - I have the following script:

/*OHTC OBJECT FUNCTION
* This function is designed to be a single global function to call the methods from a "model" in a more object oriented approach
*
* PARAMETERS:
* 0 : array : "objectPath" the file path to find the desired function. Each entry should be a string of a folder, and the 
* 		final one should be the method name. The final must NOT include the .sqf file extension
* 1 : array : "parameters" the array of parameters to pass to the desired class/script - these will be passed as is without manipulation.
* 		NOTE that a null value will be replaced with a new and empty array
* An example call of this function:
* 	[["ohtc","unit","new"],[_unit]] call ohtc_fnc_obj;
* The above would call the execVm of the file at: ohtc/unit/new.sqf
*/

//Define our variabless
private ["_parameters","_objectPath","_result","_mypath"];
_objectPath = [];
if(typeName (_this select 0) == "ARRAY") then {
_objectPath = _this select 0;
};
_parameters = [];
if(typeName (_this select 1) == "ARRAY") then {
_parameters = _this select 1;
};
_mypath = "";
_result = "";

diag_log format ["obj: entered with: parameters: %1, and objectPath: %2",_parameters,_objectPath]; 
diag_log format ["obj: parameters type: %1, and objectPath type: %2",typeName _parameters,typeName _objectPath];
diag_log format ["obj: objectPath[0]: %1",_objectPath select 0];
//If the user has passed null parameters - we replace that with a new array

//Now the logic
try {
diag_log format ["obj: in try block: objectPath[0]: %1",_objectPath select 0];
//Validate that the user has passed us an object path, and that if it is there - its not null
/*
if((count _objectPath) == 0) then {
	//Throw the 101 error code
	diag_log "obj: objectPath is not an array or is empty";
	throw "100";
};
*/

diag_log format ["obj: _mypath type: %1",typeName _mypath];

//Now attempt to concatenate the string and call the exec vm requested
//loop through the array of folders and construct the path
_mypath = _objectPath select 0;
diag_log "obj: initial path is: " + _mypath;
for "_x" from 1 to (count _objectPath) do {
	_mypath = _mypath + "\" + (_objectPath select _x);
};
_mypath = _mypath + ".sqf";
diag_log "obj: path constructed as: " + _mypath;
_result = _parameters execVM _mypath;
} catch {
diag_log "obj: WARNIng caught an exception: " + _exception;
/*
case "100": {
	_nul = [["ohtc","exception","new"],["OHTC_OBJECT_FUNCTION_100", "The objectPath must not be null, or empty"]] call ohtc_fnc_obj;
};
default {
	//Wups - we caught an unhandled exception!
	_nul = [["ohtc","exception","new"],["OHTC_OBJECT_FUNCTION_UNKNOWN", "An unknown exception was caught"]] call ohtc_fnc_obj;
};
*/
};
_result

When I run it - my log shows as follows:

21:31:28 No owner
21:31:42 Cannot load sound 'a3\ui_f\data\sound\onclick.wss'
21:31:42 "obj: entered with: parameters: ["here is what i passed"], and objectPath: ["ohtc","testFunction"]"
21:31:42 "obj: parameters type: ARRAY, and objectPath type: ARRAY"
21:31:42 "obj: objectPath[0]: ohtc"
21:31:42 "obj: in try block: objectPath[0]: ohtc"
21:31:42 "obj: _mypath type: STRING"
21:31:42 "obj: initial path is: "
21:31:42 "obj: path constructed as: "
21:31:42 Error in expression <+ (_objectPath select _x);
};
_mypath = _mypath + ".sqf";
diag_log "obj: path co>
21:31:42   Error position: <_mypath + ".sqf";
diag_log "obj: path co>
21:31:42   Error Undefined variable in expression: _mypath
21:31:42 File mpmissions\OHTC_FPOC_Blank_Mission.Altis\ohtc\fn_obj.sqf, line 53
21:31:42 Error in expression < exception: " + _exception;









};
_result>
21:31:42   Error position: <_result>
21:31:42   Error Undefined variable in expression: _result
21:31:42 File mpmissions\OHTC_FPOC_Blank_Mission.Altis\ohtc\fn_obj.sqf, line 68

Why the heck is _mypath undefined?!

Share this post


Link to post
Share on other sites

Code blocks are a separate environment, so if you rely on variables, they absolutely must be passed to it. Try this:

/*OHTC OBJECT FUNCTION 
* This function is designed to be a single global function to call the methods from a "model" in a more object oriented approach 
* 
* PARAMETERS: 
* 0 : array : "objectPath" the file path to find the desired function. Each entry should be a string of a folder, and the  
*         final one should be the method name. The final must NOT include the .sqf file extension 
* 1 : array : "parameters" the array of parameters to pass to the desired class/script - these will be passed as is without manipulation. 
*         NOTE that a null value will be replaced with a new and empty array 
* An example call of this function: 
*     [["ohtc","unit","new"],[_unit]] call ohtc_fnc_obj; 
* The above would call the execVm of the file at: ohtc/unit/new.sqf 
*/ 

//Define our variabless 
try
{
private ["_parameters","_objectPath","_result","_mypath"];
_objectPath = [];
if(typeName (_this select 0) == "ARRAY") then {
	_objectPath = _this select 0;
};
_parameters = [];
if(typeName (_this select 1) == "ARRAY") then {
	_parameters = _this select 1;
};

//	_objectPath = [_this, 0, [], [[]]] call BIS_fnc_param; //this would be shorter than what you have
//	_parameters = [_this, 0, [], [[]]] call BIS_fnc_param;

_mypath = "";
_result = "";

diag_log format ["obj: entered with: parameters: %1, and objectPath: %2",_parameters,_objectPath];
diag_log format ["obj: parameters type: %1, and objectPath type: %2",typeName _parameters,typeName _objectPath];
diag_log format ["obj: objectPath[0]: %1",_objectPath select 0];

//moved "try" to the top

diag_log format ["obj: in try block: objectPath[0]: %1",_objectPath select 0];
//Validate that the user has passed us an object path, and that if it is there - its not null
/*
if((count _objectPath) == 0) then {
	//Throw the 101 error code
	diag_log "obj: objectPath is not an array or is empty";
	throw "100";
};
*/

diag_log format ["obj: _mypath type: %1",typeName _mypath];

_mypath = _objectPath select 0;
diag_log "obj: initial path is: " + _mypath;
for "_x" from 1 to (count _objectPath) do //should be from 0 to ((count _objectPath) - 1)...unless the first element is not important?
{
	_mypath = _mypath + "\" + (_objectPath select _x);
};
_mypath = _mypath + ".sqf";
diag_log "obj: path constructed as: " + _mypath;
_result = _parameters execVM _mypath;
} catch
{
diag_log "obj: WARNIng caught an exception: " + _exception;
/*
case "100":
{
	_nul = [["ohtc","exception","new"],["OHTC_OBJECT_FUNCTION_100", "The objectPath must not be null, or empty"]] call ohtc_fnc_obj;
};
default
{
	//Wups - we caught an unhandled exception!
	_nul = [["ohtc","exception","new"],["OHTC_OBJECT_FUNCTION_UNKNOWN", "An unknown exception was caught"]] call ohtc_fnc_obj;
};
*/
};
_result

Also, using BIS_fnc_param should be able to help condense your code, I have provided an example.

Share this post


Link to post
Share on other sites

_objectpath select 0 is returning nothing for whatever reason, I don't think it's scoping however.

And at this current moment in time all of this is mushing together, as it's late, so I can't see what could be causing it.

But as some helpful info, for the following:

_objectPath = []; 
if(typeName (_this select 0) == "ARRAY") then { 
   _objectPath = _this select 0; 
}; 
_parameters = []; 
if(typeName (_this select 1) == "ARRAY") then { 
   _parameters = _this select 1; 
}; 

You could use BIS_fnc_param instead, it's a bit cleaner and you can define defaults (for debugging later down the road):

_objectpath = [_this, 0, [],[[]]] call BIS_fnc_param;
_parameters = [_this, 1, [], [[]]] call BIS_fnc_param;

//example debug

if (count _objectpath isEqualTo 0) exitWith { diag_log "_objectpath undefined"; };

EDIT: Ninja'd

Share this post


Link to post
Share on other sites

[color="#FF8040"][color="#191970"][b]for[/b][/color] [color="#7A7A7A"]"_x"[/color] [color="#191970"][b]from[/b][/color] [color="#FF0000"]1[/color] [color="#191970"][b]to[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#191970"][b]count[/b][/color] [color="#1874CD"]_objectPath[/color][color="#8B3E2F"][b])[/b][/color] [color="#191970"][b]do[/b][/color] [color="#8B3E2F"][b]{[/b][/color] 
[color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#7A7A7A"]"\"[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#1874CD"]_objectPath[/color] [color="#191970"][b]select[/b][/color] [color="#000000"]_x[/color][color="#8B3E2F"][b])[/b][/color][color="#8B3E2F"][b];[/b][/color] 
[color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color][/color]

Made with KK's SQF to BBCode Converter

should be

[color="#FF8040"][color="#191970"][b]for[/b][/color] [color="#7A7A7A"]"_x"[/color] [color="#191970"][b]from[/b][/color] [color="#FF0000"]0[/color] [color="#191970"][b]to[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#191970"][b]count[/b][/color] [color="#1874CD"]_objectPath[/color] [color="#8B3E2F"][b]-[/b][/color] [color="#FF0000"]1[/color][color="#8B3E2F"][b])[/b][/color] [color="#191970"][b]do[/b][/color] [color="#8B3E2F"][b]{[/b][/color] 
[color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#7A7A7A"]"\"[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#1874CD"]_objectPath[/color] [color="#191970"][b]select[/b][/color] [color="#000000"]_x[/color][color="#8B3E2F"][b])[/b][/color][color="#8B3E2F"][b];[/b][/color] 
[color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color]
[/color]

Made with KK's SQF to BBCode Converter

or even better

[color="#FF8040"][color="#8B3E2F"][b]{[/b][/color]
[color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#7A7A7A"]"\"[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#000000"]_x[/color][color="#8B3E2F"][b];[/b][/color] 
[color="#8B3E2F"][b]}[/b][/color] [color="#191970"][b]forEach[/b][/color] [color="#1874CD"]_objectPath[/color][color="#8B3E2F"][b];[/b][/color][/color]

Made with KK's SQF to BBCode Converter

Share this post


Link to post
Share on other sites
{
_mypath = _mypath + "\" + _x; 
} forEach _objectPath;

Could that be improved further in terms of speed by using count?

{
_mypath = _mypath + "\" + _x; 
} count _objectPath;

Share this post


Link to post
Share on other sites
Could that be improved further in terms of speed by using count?

{
   _mypath = _mypath + "\" + _x; 
} count _objectPath;

Honestly, I think this is a myth and I'm not sure how it started. I did some (admittedly primitive) testing using BIS_fnc_codePerformance and both commands showed almost identical speeds.

Also, if you use count you need to return a boolean value at the end.

Share this post


Link to post
Share on other sites
Honestly, I think this is a myth and I'm not sure how it started. I did some (admittedly primitive) testing using BIS_fnc_codePerformance and both commands showed almost identical speeds.

Also, if you use count you need to return a boolean value at the end.

I assume BIKI wouldn't lie to us:

https://community.bistudio.com/wiki/Code_Optimisation#forEach_vs_count

Edited by JShock

Share this post


Link to post
Share on other sites

Well it looks like KK first added that piece of info to the page, perhaps it's no longer the case or perhaps my results are simply false?

The only way to tell for sure is to test it yourself.

Share this post


Link to post
Share on other sites
Well it looks like KK first added that piece of info to the page, perhaps it's no longer the case or perhaps my results are simply false?

The only way to tell for sure is to test it yourself.

Pretty sure you raised this question before and pretty sure I showed you that it is still valid.

Share this post


Link to post
Share on other sites

And on a small scale like this the difference in performance is negligible, but I was just clarifying a "faster" possibility, and I did forget to put in the boolean return, below is fixed:

{
   _mypath = _mypath + "\" + _x; 
} count _objectPath > 0;  

Share this post


Link to post
Share on other sites
Well it looks like KK first added that piece of info to the page, perhaps it's no longer the case or perhaps my results are simply false?

The only way to tell for sure is to test it yourself.

Here just did the test for you, can we finally lay this to rest please?

[color="#FF8040"]arr [color="#8B3E2F"][b]=[/b][/color] [color="#8B3E2F"][b][[/b][/color][color="#8B3E2F"][b]][/b][/color][color="#8B3E2F"][b];[/b][/color] 
[color="#191970"][b]for[/b][/color] [color="#7A7A7A"]"_i"[/color] [color="#191970"][b]from[/b][/color] [color="#FF0000"]1[/color] [color="#191970"][b]to[/b][/color] [color="#FF0000"]1000[/color] [color="#191970"][b]do[/b][/color] [color="#8B3E2F"][b]{[/b][/color]
arr [color="#191970"][b]pushBack[/b][/color] [color="#FF0000"]1[/color][color="#8B3E2F"][b];[/b][/color]
[color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color]

[color="#8B3E2F"][b][[/b][/color][color="#7A7A7A"]'{} count arr'[/color][color="#8B3E2F"][b]][/b][/color] [color="#191970"][b]call[/b][/color] bis_fnc_codePerformance[color="#8B3E2F"][b];[/b][/color] [color="#006400"][i]//1.02ms[/i][/color]

[color="#8B3E2F"][b][[/b][/color][color="#7A7A7A"]'{} forEach arr'[/color][color="#8B3E2F"][b]][/b][/color] [color="#191970"][b]call[/b][/color] bis_fnc_codePerformance[color="#8B3E2F"][b];[/b][/color] [color="#006400"][i]//1.77ms[/i][/color][/color]

Made with KK's SQF to BBCode Converter

Share this post


Link to post
Share on other sites
Pretty sure you raised this question before and pretty sure I showed you that it is still valid.

I don't believe I've ever spoken to you about this? :confused: I appreciate the evidence though.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×