Is this a bug with AS3 conditional compilation? - actionscript-3

In our code I have the following, for now please ignore the //* bits;
if (data["someKey"] != null)//*
{
CONSOLE_OUT.info("Print some stuff.");
TARGET::myTarget
{
var someString:String = data["someKey"] as String;//*
someController.setSoemthing(someString.indexOf("soemthing") > -1 ? true : false);//*
}
}
I have set up my FlashCS4 to have the TARGET::myTarget compiler constant set to false, meaning that the code within the compiler constant shouldn't be compiled. At the point of execution data["someKey"] evaluates to null meaning the if statement should NOT execute.
When I debug the following code, the lines with //* on them execute, which is strange behaviour. It skips the initial line after the if statement and goes straight to executing the code that shouldn't have been compiled, bearing in mind that it shouldn't enter the if statement anyway. Its almost as if the presence of the compiler constant is causing the if statement to appear to be a single line, and then still executing the code within the wrong scope.
However, if I add an else statement on the end, the code executes fine;
if (data["someKey"] != null)//*
{
CONSOLE_OUT.info("Print some stuff.");
TARGET::myTarget
{
var someString:String = data["someKey"] as String;
someController.setSoemthing(someString.indexOf("soemthing") > -1 ? true : false);
}
}
else
{
CONSOLE_OUT.info("Print some other stuff.");
}
It should also be noted that in the instance where data["someKey"] evaluates to something other than null, the above version will correctly skip (or not compile) the code within the constant.
I just want to find out if this is a bug, or if I am not using the correct syntax for the compiler constant. If you need any more information then please let me know. I've double check my compiler constants, I am using Flash CS4 to compile and targeting Flash Player 10 if that makes a difference.

Its not bug, compiler will strip any if(false) statement so your conditional constant must be wrapped in condition evaluation.
if (data["someKey"] != null)//*
{
    CONSOLE_OUT.info("Print some stuff.");
    if(TARGET::myTarget) // it should be conditional statement
    {
        var someString:String = data["someKey"] as String;//*
        someController.setSoemthing(someString.indexOf("soemthing") > -1 ? true : false);//*
    }
}
If you look at flex sample, they have applied symbol outside method declaration, so when you write conditional compilation symbol outside member body, member body is included/excluded, but in case of inline statement, flex has no way to determine what to exclude, so it should be used in condition within if.
See answers and links here,
Flash/Flex conditional compilation "else"

I am not sure what you are doing with the TARGET static class.
I have never seen anything like that and without know what TARGET is I wouldn't know how to correct it.
In any case in your if statement you are testing if someKey has a value, however if someKey has not been defined then it wouldn't be null it would be undefined.
With that being said you need to test for it and the proper way to test for it would be like so.
if( data.hasOwnProperty("someKey"){
CONSOLE_OUT.info("Print some stuff.");
TARGET::myTarget <<<<<<< WTH is this????????
{
var someString:String = data["someKey"] as String;
someController.setSoemthing(someString.indexOf("soemthing") > -1 ? true : false);
} }
Also Note that the characters "/*" denote the start of a comment block and all code after that will be commented out.
For example
/* this would be commented
this would be commented
*/
this line would not be commented
[EDIT]
Notice how the first "i.e" is showing the property as undefined.
trace(null == undefined); //Outputs true
trace(null === undefined); //Outputs false
var i:Object;
trace(i); //Outputs null
i = {};
trace(i); //Outputs [object Object]
var i:Object = {a:"b", c:"d"};
trace(i.e); //Outputs undefined
i.e = "f";
trace(i.e); //Outputs f
reference

Related

Google Script - if criteria met run certain functions else do nothing

I have the below script with the purpose of retrieving the value in the google sheet which will either state TRUE or FALSE. If it states false I want this script to run the two functions below (updateWIPdata and updateDebtorsdata) but if the cell value is true I don't want those functions to run at all but the functions seem to run regardless of the value in the cell so any help would be much appreciated
function updateAll() {
var updateStatus = SpreadsheetApp.getActive().getSheetByName('Updated').getRange('C2').getValue();
Logger.log(updateStatus);
if (updateStatus = 'false') {
updateWIPdata();
updateDebtorsdata();
}
}
Probably the value is a boolean.
Also, please use == or ===
if (updateStatus == false) {
Reference:
Equality operators
The fix is simple
But you also want to improve a few things in your code
The main problem is in this line:
if (updateStatus = 'false')
You are not comparing updateStatus to false, you are assigning 'false' to updateStatus. On top of that you are assigning a string, not a boolean. The line needs to be
if (false === updateStatus)
Notice three things:
false is a boolean here, it doesn't have quotation marks around it
It's on the left side of the comparison; putting litteral values on the left side is a habbit that prevents this type of error
I'm using the === comparison operator instead of the = assignment operator
Another thing you need to do is forget about var and start using const and let. If your updateStatus was a const, you would have very quickly realized the error.

AS3 Boolean seemingly not working

Ok, so this is obviously going to be something that I stupidly overlooked in my code, but I am having problems with a boolean check in as3. In the below if statement I set a boolean, I can confirm that the boolean is set in this if switch as I have run a trace to check that:
if(switchA && switchB){
if(Side == "LEFT"){
localAttachCoords.x = (-Parent.collision.SideLength - entity.collision.SideLength)/2
localAttachCoords.y = Parent.collision.SideLength/2 - (((TargNode-1)*8) + entity.collision.SideLength/2)
}
if(Side == "RIGHT"){
localAttachCoords.x = (Parent.collision.SideLength + entity.collision.SideLength)/2
localAttachCoords.y = -(Parent.collision.SideLength/2 - (((TargNode-1)*8) + entity.collision.SideLength/2))
}
if(Side == "UP"){
localAttachCoords.y = (Parent.collision.SideLength + entity.collision.SideLength)/2
localAttachCoords.x = -(Parent.collision.SideLength/2 - (((TargNode-1)*8) + entity.collision.SideLength/2))
}
if(Side == "DOWN"){
localAttachCoords.y = (-Parent.collision.SideLength - entity.collision.SideLength)/2
localAttachCoords.x = Parent.collision.SideLength/2 - (((TargNode-1)*8) + entity.collision.SideLength/2)
}
entity.attached = true
entity.Parent = Parent
}
This would all be well and good, but for the fact that in a function from another class, executed every frame, claims that the boolean was set to false, I confirmed this with another trace function.
This is the function, taken from the class whose instance is referred to as entity in the above switch:
public function update(){
if (physics) physics.update()
if (node && physics){
trace(attached)
if(attached){
physics.nodeUpdate()
}
}
}
This function claims in the trace that attached == false despite it being set true earlier with no other reference to the attached variable. Any help would be appreciated!
Pathing
There are some un-addressed variables in your issue, foremost being the pathing you're taking to check your variable. This is relevant because of namespaces/scope affect what each piece of code has access to.
If your functions and variables shared the same space (i.e., global/document/timeline), then any reference the the same named variable will always return the same value, unless (as LoremIpsum noted) it's being shadowed by a local variable by the same name.
Obviously, this is not the case since you're using public function which is a class-only declaration. If the boolean you're looking for is on the timeline, and the class wants to read that variable, you need to have a valid path to it. Instantiated classes that are DisplayObjects and have been added to the DisplayList have both parent and stage properties which you can use to access the timeline global namespace (thereby providing access to your boolean).
However, if the class is not a DisplayObject (e.g., it does not extend a Sprite, Shape, or MovieClip), then access to the timeline has to be provided manually, either by setting a property on the class, or passing an argument to a method on the class.
Further complicating the matter is if the Boolean exists in another class object (either instantiated or static), you'd then need a way to get between them. A case of A sees B, C sees B, but neither A or C see eachother.
Values
A boolean is always going to be false, even if the assigned value was null, so if your class is trying to reference a variable that it can't see, that value will always be false. For example...
var foo:Boolean = this["fiddlesticks"];
trace("foo = " + foo); // traces: "foo = false"
There is no property this.fiddlesticks, so while the resolved value is null, foo becomes false. Consider using hasOwnProperty(), which indicates whether an object has a specified property defined, and is a method available to all objects.
Switch
You don't have to manually create your own switch using if then else if, AS3 has its own switch statement.
switch (Side) {
case "LEFT":
// Do stuff for left
break;
case "RIGHT":
// Do stuff for right
break;
case "UP":
// Throw your hands up
break;
case "DOWN":
// Get down and boogie!
break;
}
I hope that all helps. I'd like to say exactly what's going on with the access to your Boolean, but there simply isn't enough information to say.
Cheers!

regexp.test() returns boolean but not on 'if' statement - always evaluates to

I am working on a standalone interface.
I have several text boxes, and all have Names and IDs.
If I run this code:
var re = /someregexp/g;
var k ="sometext";
textBoxOne.setText(re.test(k)); //textBoxOne was selected first
The correct result 'true' or 'false' is displayed.
asking for a 'typeof(re.test(k))' correctly returns boolean.
However this code:
if (re.test(k)) {
textBoxTwo.setText("matched.");
} else {
textBoxTwo.setText("NOT matched.");
}
Always goes into the 'else' branch. if (re.test(k) == true) renders the same result.
Looks like a bug to me, anyone else also found this?
Edit: AdamL has pointed out (thanks Adam), in his comments below, that there is more to this than I supposed. I leave my original code below for reference.
The myFunction2() below follows the "matched" branch as you would expect a correctly working regex (so perhaps this can be used to work around the bug):
function myFunction2() {
var k ="sometext";
Logger.log( /ome/g.test(k) );
if ( /ome/g.test(k) ) {
Logger.log("matched.");
} else {
Logger.log("NOT matched.");
}
}
Conversely, as you have observed, the myFunction() below unexpectedly follows through to the "NOT matched" branch.
function myFunction() {
var re = /ome/g;
var k ="sometext";
Logger.log(re.test(k));
if (re.test(k)) {
Logger.log("matched.");
} else {
Logger.log("NOT matched.");
}
}

What does this line of Actionscript do?

I'm looking at the as3delaunay library and most of the code is clear to me. This part is not, however (note the line that I put preceded with an arrow):
public function circles():Vector.<Circle>
{
var circles:Vector.<Circle> = new Vector.<Circle>();
for each (var site:Site in _sites)
{
var radius:Number = 0;
var nearestEdge:Edge = site.nearestEdge();
=======>> !nearestEdge.isPartOfConvexHull() && (radius = nearestEdge.sitesDistance() * 0.5);
circles.push(new Circle(site.x, site.y, radius));
}
return circles;
}
For reference, isPartOfConvexHull() is found in Edge.as and looks like this:
internal function isPartOfConvexHull():Boolean
{
return (_leftVertex == null || _rightVertex == null);
}
What does !nearestEdge.isPartOfConvexHull() do? Does that mean that the radius = nearestEdge.sitesDistance() * 0.5 only executes if false is returned from the call to isPartOfConvexHull()? Does that stop execution of any other code?
It is equivalent to:
if (!nearestEdge.isPartOfConvexHull()) {
radius = nearestEdge.sitesDistance() * 0.5;
}
In the following line:
var b:Boolean = expression1 && expression2;
expression2 will not be evaluated if expression1 is false because we already know the final result: b = false.
Now in the following line:
expression1 && expression2;
The same thing happens except the fact that we are not assigning the result to a variable.
And this is exactly what happens in the line you are asking about where !nearestEdge.isPartOfConvexHull() is the first expression and (radius = nearestEdge.sitesDistance() * 0.5) is the second expression.
To extends #sch answer with some explanations (I didn't knew if editing answer to almost double it was ok).
This is based on lazy execution of the interpreter. If (!nearestEdge.isPartOfConvexHull()) is False then there's no need to execute the second part of the AND statement to know it'll be False, then it's left unexecuted. If it's true the evaluation of the complete statement is needed (and then done) to tell wether or not this boolean is True. So this is equivalent to an if statement.
TMHO this is bad code since it's to much condensed and hard to understand.

AS3 odd or even (mal)function

please
how to fix this AS3 function ?
thank you
function dispari(numero:int):Boolean;
{
//check if the number is odd or even
if (numero % 2 == 0)
{
returns false;
}
else
{
returns true;
}
}
ERROR:
1071: Syntax error: expected a definition keyword (such as function) after attribute returns, not false.
Why do you have a semi-colon (;) at the end of your function statement? I don't do any AS3 coding but it doesn't look right, and a cursory glance at a few samples on the web don't have it there.
I suspect that may be what's causing your problem. Try this instead:
function dispari(numero:int):Boolean
{
//check if the number is odd or even
if (numero % 2 == 0)
{
return false;
}
else
{
return true;
}
}
I've also changed the return statements to match what every other piece of AS3 does to return values (thanks, #Herms, forgot to mention that :-)
Pax is correct with there answer, but you can simplify it by just returning the result:
function dispari(numero:int):Boolean
{
return (numero % 2 != 0);
}