Testing Boolean in Actionscript for null - actionscript

I have a Boolean variable in Actionscript 3.
How can I check if it's undefined (not by being false) because false is a value or Boolean in Actionscript is FALSE by default >

If you want a Boolean that can be undefined (essentially a tri-state flag), you can use an Object reference, but just assign the Boolean values true and false to it. Downside is that you lose the type safety.
var isSet:Object = null;
// Later...
isSet = true;

In ActionScript, Boolean can have either true or false value only. If you don't specify any value, it is initialized to false by default.
Edit: This behavior is different from Java's Boolean object type which is a wrapper over primitive boolean. See #Victor's comments below

Related

Why flow analysis doesn't work when using bool?

void main() {
int? foo;
var isNonNull = foo != null;
if (isNonNull) foo.isEven; // Error
}
I already did a check on foo and stored its value in isNonNull variable. I could understand that warning if the scope wasn't local.
Note: I know I can use ! bang operator to resolve it but why flow analysis isn't working?
Dart type promotion is based on a check of a variable going a particular way dominating a later use of that variable.
So, if you do if (x != null) x.foo();, it detects that the check x != null being true means that the later x.foo() is valid. That only works because the compiler can also convince itself that the variable's value doesn't change between the check and the use.
If you introduce an extra boolean variable, like here, then the check is no longer performed inside the branch. That doesn't make it impossible to remember that the isNonNull boolean value being true means that foo is non-null, but it gets more complicated. The compiler now has to ensure that foo doesn't change and that isNotNull doesn't change.
The Dart compiler bails out instead, it doesn't track that level of complication. It only tracks promotion through one variable at a time.
You get the error because flow analysis can't know if isNonNull is ever going to get a new value. Take this example:
final random = Random();
void main() {
int? foo;
var isNonNull = foo != null;
isNonNull = random.nextBool();
if (isNonNull) foo.isEven;
}
So, its better to use
if (foo != null) foo.isEven;

How to simulate undefined in Dart

In JS, there is undefined and null. Undefined means "no value", null means "value equivalent to emptiness".
In Dart however (and possibly in other languages, I don't know, but right now I'm using Dart), there is no undefined, only null. Therefore it is impossible to make the distinction between a value equivalent to emptiness and the absence of value.
Is there a standard way of simulating this difference in Dart?
No. The null value (of type Null) is the only built-in value that represents the absence of a value. It does not distinguish on why the value is absent.
It's also (almost) the only type you can combine with another type directly in the type system. With null safety, you'll be able to write int? for int-or-Null.
If you want another marker for absence, you can use (or write) an Option type like:
abstract class Option<T> {
final T value;
bool get hasValue => true;
Option(this.value);
factory Option.none() => const _OptionNone();
}
class _OptionNone implements Option<Never> {
const _OptionNone();
bool get hasValue => false;
T get value => throw UnsupportedError("None option has no value");
}
Then you can represent either value or no value.
(There are existing implementations of such a class, for example in the quiver package).

How do I create field with Bool type for Record Type?

When I try to add a new field to record type, there is no possibility to add a Bool type. How can I do this anyway?
Referring to Creating a Database Schema by Saving Records Apple Documentation, the following table contains CloudKit possible field types:
unfortunately, there is no Bool type found. What I find -logically- is the most suitable to be a replacement of Bool is the Int(64), because:
Int(64) class -as mentioned in the table- is NSNumber which has a boolValue which returns a Swift Bool:
The number object's value expressed as a Boolean value. A 0 value
always means false, and any nonzero value is interpreted as true.
For more details, check the NSNumber documentation.
Which leads to the ease of treating them as Bool inside your application. For example:
let myFalseNumber:NSNumber = 0.0
let myTrueNumber:NSNumber = 0.01232
let anotherTrueNumber: NSNumber = -99
print(myFalseNumber.boolValue) // false
print(myTrueNumber.boolValue) // true
print(anotherTrueNumber.boolValue) // true
Although both Int(64) and Double are treated as NSNumber, the reason why choosing Int(64) instead of Double (CloudKit Type) is the generality of treating "1 if true and 0 if false" (without any floating points). For more information, you might want to check Boolean data type - Generalities (Wikipedia).
Hope it helped.
There is no Bool type available for CKRecord.The best option is Int(64).
Source Apple Documentation

What values should I use for iOS boolean states?

It appears that in iOS I have a number of options that seem to fit for boolean values:
YES
NO
TRUE
FALSE
true
false
Which ones should I use? In this particular case I'm hiding a label, so should I set the hidden property to YES, TRUE, or true?
Short answer: you should prefer YES and NO for setting foundation properties of type BOOL.
For the long answer, let's first see where are these constants defined:
true and false are from stdbool.h; they are #define-d as 1 and 0
TRUE and FALSE are from CFBase.h; they are #define-d as 1 and 0
YES and NO are from NSObjCRuntime.h. This is where signed char is typedef-ed as BOOL, and its two values are #define-d as ((BOOL)1) and ((BOOL)0) or __objc_yes/__objc_no if objc_bool is supported.
The foundation classes consistently use BOOL, which is a typedef for signed char, to represent its boolean properties. Since the first two pairs get converted to int constants, using them may result in warnings, though it would probably work correctly anyway. The YES and NO constants, however, are defined in the most compatible way for your compiler, regardless of its version. Therefore, I would recommend using YES and NO consistently throughout your code.
Actually there is no difference between YES, TRUE and true those all represent a true state represented by 1.
And NO, false, FALSE is represents a false state represented by 0.
You can also use:
BOOL aBool = 1;
which is equivalent to BOOL aBool = true; and BOOL aBool = TRUE; and BOOL aBool = YES;
But:
BOOL bBool = 7;
if (bBool)
{
NSLog(#"bBool is YES!\n");
}
if (bBool != YES) {
NSLog("bBool is not YES!\n");
}
Will output like:
b is YES!
b is not YES!
This is because direct comparison with YES will fail when the value of a BOOL type is a non-zero value other than 1.
Here is a nice article for you.
I think all of them are okay. But personally, I'd like to use YES/NO.
I found a doc called Objective-C Runtime Reference:
Boolean Values
These macros define convenient constants to represent Boolean values.
#define YES (BOOL)1
#define NO (BOOL)0
Constants
YES
Defines YES as 1.
Available in iOS 2.0 and later.
Declared in NSObjCRuntime.h.
NO
Defines NO as 0.
Available in iOS 2.0 and later.
Declared in NSObjCRuntime.h.
Declared In
objc.h
I share your view on this, whilst they are currently all defined the same, porting the code is a pain when you may find TRUE != true. (Precisely why we should never test X == 1 for TRUE as some languages use -1 and some use 1)
I think it might be personal preference and mainly about future ports.
I follow the TRUE and FALSE options so that porting to C/C++ is easier.
You may find that true and false is better if you're regularly converting code to Java so there's less search/replaces but I found consistency with Cocoa easier.
Use YES and NO is the same to use TRUE and FALSE or 1 and 0 respectively.
And use NSLog to view result like this little example:
BOOL result;
result = YES;
NSLog(#"my boolean result is %#",result ? #"Yes" : #"No");

Toggling Boolean Problem

this code is written in simple ActionScript, but i'm assuming this problem of mine would occur in all languages that have boolean datatypes.
i'm simply clicking the stage so that my boolean variable reverses its value and than traces/prints/logs it's new value. however, it's always tracing true instead of switching between true and false for each mouse click.
what am i doing wrong?
var myBool:Boolean;
stage.addEventListener(MouseEvent.CLICK, mouseClickHandler);
function mouseClickHandler(evt:MouseEvent):void
{
changeBoolean(myBool);
}
function changeBoolean(boolean:Boolean):void
{
boolean = !boolean;
trace(boolean);
}
You are passing a value to the function, not the reference. This means that boolean value inside your changeBoolean function is copied from myBool variable so when you changed it inside the function, it didn't realy change myBool variable. There are basically two solutions to this:
change the function to not accept parameters and inside it change myBool variable or
change the function so that it returns the boolean parameter and on calling the function, set the myBool valu to the result of the function
In the function changeBoolean, you're changing the value of the boolean (poor name, by the way - try to avoid naming collisions with built-in types, even with different casing) parameter. This has no effect outside that function.
You want to change the value of myBool (which I would call a class field in .Net or Java) instead.
function mouseClickHandler(evt:MouseEvent):void
{
myBool = !myBool;
trace(myBool);
}
...is what I would do (again, with a naive understanding of ActionScript).

Resources