I wrote a firestore rule like this:
function isPublished() {
return !('publicationAt' in resource.data.keys()) ? true :
debug(debug(request.time) >= debug(resource.data.publicationAt));
}
and in my app i´m saving several datetimes just with new Date();
Now, I´d like to get a list of all items that are published - but it gives me an evaluation error - with this debug:
constraint_value {
simple_constraints {
comparator: LTE
value {
timestamp_value {
seconds: 1669108946
nanos: 684000000
}
}
}
}
timestamp_value { seconds: 1669108945 nanos: 727000000 }
Can someone give me a hint what I´m doing wrong?
While you may be tempted to think that Security Rules Language (SRL) is JavaScript because of the function() {} part, it is not. It is a special statically evaluated language that gets interpreted once without other common features like iteration.
Importantly, the SRL has no ternary operator:
<condition> ? <result-when-true> : <result-when-false>
Instead you must build your conditions as a sequence of Boolean tests making use of the available helper methods and classes.
The equivalent in basic Boolean algebra of the ternary operator (when using short-circuiting operators like && and ||) is:
(<condition> && <result-when-true>) || (NOT(<condition>) && <result-when-false>)
Substituting in the value for <result-when-true>, we can reduce down your expression using Boolean algebra laws (where the AND operator (&&) is ∧ and the OR operator (||) is ∨):
(<condition> && <result-when-true>) || (NOT(<condition>) && <result-when-false>)
// replace <result-when-true> with TRUE, as in your question
(<condition> && TRUE) || (NOT(<condition>) && <result-when-false>)
// now remove the redundant "&& TRUE" (see "Identity of ∧")
<condition> || (NOT(<condition>) && <result-when-false>)
// now distribute the OR operator (see "Distributivity of ∨ over ∧")
(<condition> || NOT(<condition>)) && (<condition> || <result-when-false>)
// now replace (<condition> || NOT(<condition>)) because it will always be TRUE (see "Complementation 2")
TRUE && (<condition> || <result-when-false>)
// now remove the redundant "TRUE &&" like before (see "Identity of ∧")
<condition> || <result-when-false>
Subsituting in the parts from your question, this leaves us with:
!('publicationAt' in resource.data.keys())
|| debug(debug(request.time) >= debug(resource.data.publicationAt))
You can also simplify 'publicationAt' in resource.data.keys() to just 'publicationAt' in resource.data (as the in operator handles what you were expecting for rules.Map objects), giving us:
!('publicationAt' in resource.data)
|| debug(debug(request.time) >= debug(resource.data.publicationAt));
This means the correct form of your SRL function would look like:
function isPublished() {
return !('publicationAt' in resource.data)
|| debug(debug(request.time) >= debug(resource.data.publicationAt));
}
While (ptr ! =NULL && dptr! = NULL && dptr->next! =NULL)
In this code if the pointer dptr is NULL will it work or will terminate?
If the statement is true or not is actually based not only on dptr but also on ptr and dptr->next. If the statement is true - the content if the while-loop will be executed.
The substatements (your camparisons to not NULL) are checked one after another - if one is false, the other will not be executed. This is true for most programming languages. Though I haven't checked with all.
Logical && as well as || have some inherent mechanism for fast return. They both go step by step from left to right substatement. (Plus () ). With && the check is aborted on the first false statement. With || the check is aborted on the first true statement. The other checks won't be reached.
So your statement will never check dptr->next != NULL for the case that dptr is actually NULL. So your statement is safe from access to NULL pointers.
So for binary operators on booleans, Java has &, |, ^, && and ||.
Let's summarize what they do briefly here:
JLS 15.22.2 Boolean Logical Operators &, ^, and |
JLS 15.23 Conditional-And Operator &&
JLS 15.24 Conditional-Or Operator ||
For &, the result value is true if both operand values are true; otherwise, the result is false.
For |, the result value is false if both operand values are false; otherwise, the result is true.
For ^, the result value is true if the operand values are different; otherwise, the result is false.
The && operator is like & but evaluates its right-hand operand only if the value of its left-hand operand is true.
The || operator is like |, but evaluates its right-hand operand only if the value of its left-hand operand is false.
Now, among all 5, 3 of those have compound assignment versions, namely |=, &= and ^=. So my question is obvious: why doesn't Java provide &&= and ||= as well? I find that I need those more than I need &= and |=.
And I don't think that "because it's too long" is a good answer, because Java has >>>=. There must be a better reason for this omission.
From 15.26 Assignment Operators:
There are 12 assignment operators; [...] = *= /= %= += -= <<= >>= >>>= &= ^= |=
A comment was made that if &&= and ||= were implemented, then it would be the only operators that do not evaluate the right hand side first. I believe this notion that a compound assignment operator evaluates the right hand side first is a mistake.
From 15.26.2 Compound Assignment Operators:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
As proof, the following snippet throws a NullPointerException, not an ArrayIndexOutOfBoundsException.
int[] a = null;
int[] b = {};
a[0] += b[-1];
Reason
The operators &&= and ||= are not available on Java because for most of the developers these operators are:
error-prone
useless
Example for &&=
If Java allowed &&= operator, then that code:
bool isOk = true; //becomes false when at least a function returns false
isOK &&= f1();
isOK &&= f2(); //we may expect f2() is called whatever the f1() returned value
would be equivalent to:
bool isOk = true;
if (isOK) isOk = f1();
if (isOK) isOk = f2(); //f2() is called only when f1() returns true
This first code is error-prone because many developers would think f2() is always called whatever the f1() returned value. It is like bool isOk = f1() && f2(); where f2() is called only when f1() returns true.
If the developer wants f2() to be called only when f1() returns true, therefore the second code above is less error-prone.
Else &= is sufficient because the developer wants f2() to be always called:
Same example but for &=
bool isOk = true;
isOK &= f1();
isOK &= f2(); //f2() always called whatever the f1() returned value
Moreover, the JVM should run this above code as the following one:
bool isOk = true;
if (!f1()) isOk = false;
if (!f2()) isOk = false; //f2() always called
Compare && and & results
Are the results of operators && and & the same when applied on boolean values?
Let's check using the following Java code:
public class qalcdo {
public static void main (String[] args) {
test (true, true);
test (true, false);
test (false, false);
test (false, true);
}
private static void test (boolean a, boolean b) {
System.out.println (counter++ + ") a=" + a + " and b=" + b);
System.out.println ("a && b = " + (a && b));
System.out.println ("a & b = " + (a & b));
System.out.println ("======================");
}
private static int counter = 1;
}
Output:
1) a=true and b=true
a && b = true
a & b = true
======================
2) a=true and b=false
a && b = false
a & b = false
======================
3) a=false and b=false
a && b = false
a & b = false
======================
4) a=false and b=true
a && b = false
a & b = false
======================
Therefore YES we can replace && by & for boolean values ;-)
So better use &= instead of &&=.
Same for ||=
Same reasons as for &&=:
operator |= is less error-prone than ||=.
If a developer wants f2() not to be called when f1() returns true, then I advice the following alternatives:
// here a comment is required to explain that
// f2() is not called when f1() returns false, and so on...
bool isOk = f1() || f2() || f3() || f4();
or:
// here the following comments are not required
// (the code is enough understandable)
bool isOk = false;
if (!isOK) isOk = f1();
if (!isOK) isOk = f2(); //f2() is not called when f1() returns false
if (!isOK) isOk = f3(); //f3() is not called when f1() or f2() return false
if (!isOK) isOk = f4(); //f4() is not called when ...
Probably because something like
x = false;
x &&= someComplexExpression();
looks like it ought to be assigning to x and evaluating someComplexExpression(), but the fact that the evaluation hinges on the value of x isn't apparent from the syntax.
Also because Java's syntax is based on C, and no one saw a pressing need to add those operators. You'd probably be better off with an if statement, anyway.
It is this way in Java, because it is this way in C.
Now the question why it is so in C is because when & and && became different operators (sometime preceding C's descent from B), the &= variety of operators was simply overlooked.
But the second part of my answer does not have any sources to back it up.
Largely because Java syntax is based on C (or at least the C family), and in C all those assignment operators get compiled to arithmetic or bitwise assembly instructions on a single register. The assignment-operator version avoids temporaries and may have produced more efficient code on early non-optimising compilers. The logical operator (as they are termed in C) equivalents (&&= and ||=) don't have such an obvious correspondence to single assembly instructions; they usually expand to a test and branch sequence of instructions.
Interestingly, languages like ruby do have ||= and &&=.
Edit: terminology differs between Java and C
One of Java's original aims was to be "Simple, Object Oriented, and Familiar." As applied to this case, &= is familiar (C, C++ have it and familiar in this context meant familiar to someone who knows those two).
&&= would not be familiar, and it would not be simple, in the sense that the language designers were not looking to think of every operator they could add to the language, so less extra operators are simpler.
For Boolean vars, && and || would use short circuit evaluation while & and | don't, so you would expect &&= and ||= to also use short circuit evaluation. There is a good use case for this. Especially if you are iterating over a loop, you want to be fast, efficient and terse.
Instead of writing
foreach(item in coll)
{
bVal = bVal || fn(item); // not so elegant
}
I want to write
foreach(item in coll)
{
bVal ||= fn(item); // elegant
}
and know that once bVal is true, fn() will not be called for the remainder of the iterations.
'&' and '&&' are not the same as '&&' is a short cut operation which will not do if the first operand is false while '&' will do it anyway (works with both number and boolean).
I do agree that it make more sense to exist but it is not that bad if it is not there. I guess it was not there because C does not have it.
Really can't think of why.
Brian Goetz (Java Language Architect at Oracle) wrote:
https://stackoverflow.com/q/2324549/ [this question] shows that there is interest in having these operators and there
are no clear arguments why they don't exist yet.
The question is therefore: Has the JDK team discussed adding these operators in the past and if so
what where the reasons against adding them?
I'm not aware of any specific discussion on this particular issue, but
if someone were to propose it, the answer would likely be: it's not an
unreasonable request, but it doesn't carry its weight.
"Carrying its weight" needs to be judged by its costs and benefits, and
by its cost-benefit ratio relative to other candidate features.
I think you are implicitly assuming (by the phrase "there is interest")
that the cost is near zero and the benefit is greater than zero, so it
seems an obvious win. But this belies an incorrect understanding of
cost; a feature like this affects the language spec, the implementation,
the JCK, and every IDE and Java textbook. There are no trivial language
features. And the benefit, while nonzero, is pretty small.
Secondarily, there are infinitely many features we could do, but we
only have capacity to do a handful every few years (and users have a
limited capacity to absorb new features.) So we have to be very careful
as to which we pick, as each feature (even a trivial-seeming one)
consumes some of this budget, and invariably takes it away from others.
It's not "why not this feature", but "what other features will we not do
(or delay) so we can do this one, and is that a good trade?" And I
can't really imagine this being a good trade against anything else we're
working on.
So, it clears the bar of "not a terrible idea" (which is already pretty
good, a lot of feature requests don't even clear that), but seems
unlikely to ever clear the bar of "a better use of our evolution budget
than anything else."
It is allowed in Ruby.
If I were to guess, I would say that it is not frequently used so it wasn't implemented. Another explanation could be that the parser only looks at the character before the =
I cannot think of any better reason then 'It looks incredible ugly!'
&
verifies both operands, it's a bitwise operator. Java defines several bitwise operators, which can be applied to the integer types, long, int, short, char, and byte.
&&
stops evaluating if the first operand evaluates to false since the result will be false, it's a logical operator. It can be applied to booleans.
The && operator is similar to the & operator, but can make your code a bit more efficient. Because both expressions compared by the & operator must be true for the entire expression to be true, there’s no reason to evaluate the second expression if the first one returns false. The & operator always evaluates both expressions. The && operator evaluates the second expression only if the first expression is true.
Having a &&= assignment operator wouldn't really add new functionality to the language. The bitwise operator's arithmetic is much more expressive, you can do integer bitwise arithmetic, which includes Boolean arithmetic. The logical operators can merely do Boolean arithmetic.
Funny I came across this question.
The operators ||= and &&= do not exist as their semantics are easily misunderstood;
if you think you need them, use an if-statement instead.
Ely (post just above) got the gist right:
||
stops evaluating if the first operand evaluates to true since the result will be true, it's a logical operator.
So imagine what will happen if b == true;
b ||= somethingreturningaboolean(); // !!??
this will not invoke somethingreturningaboolean(), if b == true.
This behavior is more obvious in the long form:
b = b || somethingreturningaboolean();
That's why ||= and &&= ops do not exist. The explanation should be given as:
The operators ||= and &&= do not exist as their semantics are easily misunderstood;
if you think you need them, use an if-statement instead.
This example can be easily tested in the groovy console.
var a is evaluated to not null while b is evaluated to null.
Both are instances of org.codehaus.groovy.runtim.NullObject
def b = null
println b.getClass()
println b == null
def a = null.getClass().newInstance()
println a.getClass()
println a == null
Does anyone knows why?
This is a tricky thing when dealing with reflection code.
Actually I am wondering if this is not a bug. As an explanation... NullObject is a runtime/intermediate kind of Object. If you do anything on null, then NullObject is used. This, and the the implementation of NullObject#equals speaks for a==null returning true. It returns fails, because there is some internal code before that, that is for example determining if compareTo is called instead of equals and such things. Now this piece of code starts with
if (left == right) return true;
if (left == null || right == null) return false;
so null==null will return true, but NullObject==null will return false. On the other hand NullObject should not leak out if possible. Maybe we should fix newInstance() to return null.
I filled http://jira.codehaus.org/browse/GROOVY-5769 for this
In the equals method of NullObject, it only returns true if you are comparing it to null
As an instance of NullObject is not strictly null, it returns false...
Whether NullObject should return true if you call equals against another NullObject is probably a question best asked on the mailing list... I'll have a look and see if I can find any previous question.
HEllo,
i try to do that in FlashBuilder (FlexProject)
protected function btn_detail_view_clickHandler(event:MouseEvent):void
{
CurrentState="Statistiques" || "PartMarche";
}
But it's not working, i guess this is not the right syntax but what's the right syntax ? Thanks
PS: i want to when the state is equal to "statistiques" or "partMarche" when i click on the button, that the current state changes to Detail view ;)
In ECMAScript languages, || is a short-circuit operator that will return the left-hand side expression result if it evaluates to a "truthy" value, or the right-hand side expression result otherwise. Non-empty strings always evaluate to truthy values, so the left-hand expression will always be returned here. The equivalent long-hand code to your example is:
if ("Statistiques")
CurrentState = "Statistiques";
else
CurrentState = "PartMarche";
This type of short circuit operator is used to set defaults to variables in certain situations:
CurrentState = PreviousState || "Some string";
In that example, if PreviousState is null or false or an empty string, CurrentState would be set to "Some string". If PreviousState is a string like "Some other string", CurrentState would be set to "Some other string".
Thanks for clarifying what you want to do. For checking what CurrentState is, you need to test it with an if condition:
if (CurrentState == "Statistiques" || CurrentState == "PartMarche")
{
// Of course, use the actual name of your detail view here
CurrentState = "DetailView";
}
Ok in fact i need to remove the .Statistiques to that code works in all the states
click.Statistiques="btn_detail_view_clickHandler(event)"
Sorry i just went too fast by myself instead of finishing the tutorial.
Your answers will prevent me to ask the next question ! thank you ;)