How do I use the CoffeeScript existential operator to check some object properties for undefined? - coffeescript

I would like to use the CoffeeScript existential operator to check some object properties for undefined. However, I encountered a little problem.
Code like this:
console.log test if test?
Compiles to:
if (typeof test !== "undefined" && test !== null) console.log(test);
Which is the behavior I would like to see. However, when I try using it against object properties, like this:
console.log test.test if test.test?
I get something like that:
if (test.test != null) console.log(test.test);
Which desn't look like a check against undefined at all. The only way I could have achieved the same (1:1) behavior as using it for objects was by using a larger check:
console.log test.test if typeof test.test != "undefined" and test.test != null
The question is - am I doing something wrong? Or is the compiled code what is enough to check for existence of a property (a null check with type conversion)?

This is a common point of confusion with the existential operator: Sometimes
x?
compiles to
typeof test !== "undefined" && test !== null
and other times it just compiles to
x != null
The two are equivalent, because x != null will be false when x is either null or undefined. So x != null is a more compact way of expressing (x !== undefined && x !== null). The reason the typeof compilation occurs is that the compiler thinks x may not have been defined at all, in which case doing an equality test would trigger ReferenceError: x is not defined.
In your particular case, test.test may have the value undefined, but you can't get a ReferenceError by referring to an undefined property on an existing object, so the compiler opts for the shorter output.

This JavaScript:
a.foo != null
actually does check if the foo property of a is neither undefined nor null. Note that a.foo? is translated to JavaScript that uses != null rather than !== null. The conversions that != does means that both of these are true:
null == null
undefined == null
A plain a? becomes this JavaScript:
typeof a !== "undefined" && a !== null
because there are three conditions to check:
Is there an a in scope anywhere?
Does a have a value of undefined?
Does a have a value of null?
The first condition is important as just saying a != null will trigger a ReferenceError if there is no a in scope but saying typeof a === 'undefined' won't. The typeof check also takes care of the a === undefined condition in 2. Then we can finish it off with a strict a !== null test as that takes care of 3 without the performance penalty of an unnecessary != (note: != and == are slower than !== and === due to the implicit conversions).
A little reading on what != and !== do might be fruitful:
MDN: Comparison Operators
As far as your comment on the deleted answer is concerned, if(a.foo) is perfectly valid syntax if you complete the if statement:
if(a.foo)
do_interesting_things()
# or
do_interesting_things() if(a.foo)
However, if(a.foo) and if(a.foo?) differ in how they handle 0, false, and ''.

Wild guess; have you tried console.log test.test if test?.test??
Just tested it with coffee -p -e 'console.log test.test if test?.test?', which compiles to:
(function() {
if ((typeof test !== "undefined" && test !== null ? test.test : void
0) != null) {
console.log(test.test); }
}).call(this);

Related

How can this property be changed to remove the error (VERI-1537)?

I'm trying to write a property as:
property seq_op_1;
logic [PW_WIDTH-1:0] mk;
((~|a_valid && !b_valid) ##1
((b_valid && b_ready && (b_len == 4'h0)),mk=b_mk) ##[1:MAX_COUNT]
(c_valid && c_ready && (c_mk == mk) && c_last));
endproperty
cover_seq_op_1 : cover property (seq_op_1);
However, when the running analysis/elaboration I get the following error:
VERI-1537: local variable 'mk' is referenced in expression where it does not flow.
What am I doing wrong here?
I could not come up with a solution to try.

flutter null safety from prefs.setStringList -> error : the argument list<String?> can't be assigned to the parameter type List <String>

Hello I try to make null safety migration, but have a probleme with
prefs.setStringList("save_list_autre2",save_list.toList());
the error is : the argument list<String?> can't be assigned to the parameter type List
RegExp regExp = new RegExp(r'(...)');
var save_list= regExp.allMatches(decrypted).map((z) => z.group(0));
if(regExp.allMatches(decrypted)==null ){
[...]
} else {
prefs.setStringList("save_list_autre2",save_list.toList());
}
I add .toString() from save_list= regExp.allMatches(decrypted).map((z) => z.group(0).toString());
the error is removed but I don't know if it's the good solution
When you call z.group(0) the group method could return null if there was no group with the given index (0 in this case). so dart thinks you might have some null values on your list of strings.
The reality is that you shouldn't get any null values because you are passing a 0. So to tell dart that the method isn't returning null, use the ! operator:
regExp.allMatches(decrypted)
.map((z) => z.group(0)!)
If, by some chance, you happened to have any null values, this code will not work (as I said, I believe you won't but what do I know? I've never used regexes with dart)
If that's the case, you first need to filter the null values and then use the !:
regExp.allMatches(decrypted)
.map((z) => z.group(0))
.where((v) => v != null) // filter out null values
.map((v) => v!); // let dart know you don't have any null values.
Hopefully that's enough to fix the problem

Confusion with Null safety

I'm pretty new to flutter and because of the null safety feature I've been getting a lot of errors from a code that will run perfectly fine in Java or other langs. For example this-
int ? i;
var icecreamFlavours = ['chocolate', 'vanilla', 'orange'];
icecreamFlavours.forEach((item) {
i++; //This is where I get the error
print('We have the $item flavour');
});
My Error Message
Error: Operator '+' cannot be called on 'int?' because it is potentially null.
i++;
Error: A value of type 'num' can't be assigned to a variable of type 'int?'.
i++;
You can't do either i++ or i+=1 on a nullable variable, because the reason is simple, null variable can have null values which will make increment no sense.
In addition to this, you can't even do i!++ or i!+=1 even if you are sure that i is not null. There is an open issue for this https://github.com/dart-lang/language/issues/1113
So for now you can do this i = i! + 1
Update:
For i = i! + 1 to work you need to be sure about i not being null. So it's better to initialise/assign i with some value before using it.

Linq where clause with nullable parameters

I'm trying to do a linq query which might have nullable params.
This is my linq call
listOfControlsVM = db.Controls.Where((status == null || s.Status.Description == status) && (impact == null || s.Impact == impact)).ToList();
Now either status or impact can be nullable params (I have two more but I removed them from the example). With the approach I have the query doesn't return the correct set of results.
I want to know if there is other better approach to work with nullable params in linq. For example if status or impact have value include them in the conditions, otherwise skip them.
There is a HasValue to check null value on nullable variable instead of null.
listOfControlsVM = db.Controls.Where((!status.HasValue || s.Status.Description == status) && (!impact.HasValue || s.Impact == impact)).ToList();
I hope this will help you out :)

Perl's "not" operator not working as expected with the defined() function

The following snippet is not working as expected:
$k{"foo"}=1;
$k{"bar"}=2;
if(not defined($k{"foo"}) && not defined($k{"bar"})){
print "Not defined\n";
}
else{
print "Defined"
}
Since both $k{"foo"} and $k{"bar"} are defined, the expected output is "Defined". Running the code, however, returns "Not defined".
Now, playing around with the code I realized that placing parentheses around each of the not defined() calls produces the desired result:
if((not defined($k{"foo"})) && (not defined($k{"bar"}))){print "Not Defined"}
I imagine this has something to do with operator precedence but could someone explain what exactly is going on?
Precedence problem.
not defined($k{"foo"}) && not defined($k{"bar"})
means
not ( defined($k{"foo"}) && not defined($k{"bar"}) )
which is equilvalent to
!defined($k{"foo"}) || defined($k{"bar"})
when you actually want
!defined($k{"foo"}) && !defined($k{"bar"})
Solutions:
!defined($k{"foo"}) && !defined($k{"bar"})
not defined($k{"foo"}) and not defined($k{"bar"})
(not defined($k{"foo"})) && (not defined($k{"bar"}))
PS - The language is named "Perl", not "PERL".