Jump to content
Sign in to follow this  
Issetea

exitWith behavior

Recommended Posts

While still converting some ArmA1 scripts to ArmA2 we've encountered a ?bug? in the exitWith command. Can someone tell me whether I'm using it wrong or it's a real ArmA bug please?

Here is a small example of the exitWith in ArmA2 (The function doesn't make much sense but it's just an example):

// Searches given Parameter in the array "_arr" and returns the array. In this example it returns: [1] for parameter: 1
INV_getitemArray = {
private ["_c", "_Fobjarray", "_arr"];
_Fobjarray = [];
_arr = [[1]];
for [{_c=0}, {_c < (count _arr)}, {_c=_c+1}] do {
	if (((_arr select _c) select 0) == _this) exitWith { _Fobjarray = _arr select _c; /* true */ };
};
hint "Still returns the array after exit.";
_Fobjarray
};

INV_getitemName = { ((_this call INV_getitemArray) select 0) };

_amount = 10;
hint format["Test-1: %1, %2", _amount, (1 call INV_getitemName)];
hint format["Test-2: %1, %2", _amount, 1];

Output:

"Still returns the array after exit."

"Test-1: <null>, 1" <- Amount should be 10, instead, it's the reutned value of the exitWith block.

"Test-2: 10, 1"

Notes

Replacing "exixtWith" with "then" fixes the problem. If we return true (At the comment above), the _amount variable in the first output will be "true" as well, in the second, it will be 10 again.

Share this post


Link to post
Share on other sites

Something does indeed look very wrong above.

I suspect exitWith or maybe even call is not correctly popping it's scope when it exits. So format is still executed inside the function scope, try adding different values to _amount inside the function scopes. My guess is one of those would be printed.

Edited by zyklone

Share this post


Link to post
Share on other sites

The value printed is always the value returned by the "exitWith". If we return true the output of amount will be true, but only in the same "hint format" the function is called. Since the amount variable stays 10 (As the second output shows), the variable is never really changed (or if, it's somehow magically changed back)

The following line in the script above would output "true" for the amount variable in the first output.

if (((_arr select _c) select 0) == _this) exitWith { _Fobjarray = _arr select _c; true };

And this one "test123"

if (((_arr select _c) select 0) == _this) exitWith { _Fobjarray = _arr select _c; test123 };

EDIT: Well thinking about it, changing the amount variable inside the function will change the amount variable outside of the function as long as it's not in the private array. However, there's no reason for it to be changed by the exitWith I think.

Edited by Issetea

Share this post


Link to post
Share on other sites

Yes, as I said it's not actually changing the variable. It's most likely looking for it in the wrong place.

There has supposedly been big changes to how variable scope works in Arma2 and something was probably missed in exitWith or format.

Either way it's a bug and I'm sure BI will look into it.

Just don't use exitWith if you don't have to. :)

Share this post


Link to post
Share on other sites

Thanks for your reply again.

I'd like not to use exitWith anymore but since we are using it 650 times this might be a problem. The breakTo command and all the other scope related commands seem to work fine though.

Share this post


Link to post
Share on other sites

Did you try using a local variable inside the format array instead of calling the function inside the array ?

_x = 1 call INV_getitemName;
hint format["Test-1: %1, %2", _amount,  _x];

Share this post


Link to post
Share on other sites

exitWith { _Fobjarray = _arr select _c; /* true */ };

just remove the ; after _c. Always the value of the last expression is returned which is nothing in this case.

EDIT: Oh, seems I missunderstood the problem. ignore me then

Edited by T_D

Share this post


Link to post
Share on other sites

Just drop the C-style for and replace it with for "_c" from 0 to... or with forEach and it'll work.

Means, either this way:

for "_c" from 0 to (count _arr - 1) do 
{
       if (((_arr select _c) select 0) == _this) exitWith { _Fobjarray = _arr select _c; /* true */};
};

or like this:

{
       if ((_x select 0) == _this) exitWith { _Fobjarray = _x; /* true */};
} forEach _arr;

But be sure to not use capital letters for the variable in for "_x" ...

Xeno

Share this post


Link to post
Share on other sites

I just replaced 260 loops and it works. Thanks for your help!

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  

×