What does the operator ?= mean? - ruby-on-rails

I have a hamlc (known as Haml + Inline CoffeeScript) which has a line like
- #variable1 ?= #object1.element[0]
I wonder if this means: if #object1.element[0] has a value then store it inside #variable1.
I cannot find any info about hamlc. Also, if what I understand is right, what if I want to add an else condition?

The ?= operator is known as the existential operator in CoffeeScript.
From the docs:
It's a little difficult to check for the existence of a variable in JavaScript. if (variable) ... comes close, but fails for zero, the empty string, and false. CoffeeScript's existential operator ? returns true unless a variable is null or undefined, which makes it analogous to Ruby's nil?
That means that the way it works is, using your example:
#variable1 ?= #object1.element[0]
If #variable1 is null or undefined, assign #object1.element[0] to it.
what if I want to add the condition for "else" ?
#variable1 =
if #variable1?
#object1.element[0]
else
# your else clause here

Related

Open policy agent satisfy condition for all array items

Trying to wrap my head around this issue for a while - I have a JSON input which contains an array, say something like this:
{
"array" : [
{"foo": "bar"},
{"foo": "buzz"},
{"misbehaving": "object"}
]
}
My goal is to verify that all of the objects in the array satisfy the condition of having a field named foo (actual use-case is to make sure that all resources in cloud deployment have tags). My issue is that standard rego expressions are evaluated as "at least" and not "all", which means that expressions like:
all_have_foo_field {
input.array.foo
}
Are always returning true, even though some objects do not satisfy this. I've looked at this, but evaluating a regex returns true or false while my policy checks if field exists, meaning if it does not I get a 'var_is_unsafe' error.
Any ideas?
There are two ways to say "all fields of elements in X must match these conditions" (FOR ALL).
TLDR:
all_have_foo_field {
# use negation and a helper rule
not any_missing_foo_field
}
any_missing_foo_field {
some i
input.array[i]
not input.array[i].foo
}
OR
all_have_foo_field {
# use a comprehension
having_foo := {i | input.array[i].foo}
count(having_foo) == count(input.array)
}
The approach depends on the us case. If you want to know what elements do not satisfy the conditions, the comprehension is nice because you can use set arithmetic, e.g., {i | input.array[i]} - {i | input.array[i].foo} produces the set of array indices that do not have the field "foo". You probably want to assign these expressions to local variables for readability. See this section in the docs for more detail: https://www.openpolicyagent.org/docs/latest/policy-language/#universal-quantification-for-all.
In this case (as opposed to the answer you linked to) we don't have to use regex or anything like that since references to missing/undefined fields results in undefined and undefined propagates outward to the expression, query, rule, etc. This is covered to some extent in the Introduction.
All we have to do then is just refer to the field in question. Note, technically not input.array[i].foo would be TRUE if the "foo" field value false however in many cases undefined and false can be treated as interchangeable (they're not quite the same--false is a valid JSON value whereas undefined represents the lack of a value.) If you need to only match undefined then you have to assign the result of the reference to a local variable. In the comprehension case we can write:
# the set will contain all values i where field "foo" exists regardless
{i | _ = input.array[i].foo}
In the negation case we need an additional helper rule since not _ = input.array[i].foo would be "unsafe". We can write:
exists(value, key) { value[key] = _ }`
And now not exists(input[i], "foo") is only TRUE when the field "foo" is missing.
Note, differentiating between undefined and false is often not worth it--I recommend only doing so when necessary.

Ada vector of enumerated type

I am trying to created a vector of an enumerated type in Ada, but the compiler seems to expect an equality function overload. How do I telll the compiler to just use the default equal function. Here's what I have:
package HoursWorkedVector is new Ada.Containers.Vectors(Natural,DAY_OF_WEEK);
--where Day of week is defined as an enumeration
When I try to compile, I get the message:
no visible subprogram matches the specification for "="
Do I need to create a comparison function to have a vector of an enumerated type? Thanks in advance.
The definition of Ada.Containers.Vectors starts like this:
generic
type Index_Type is range <>;
type Element_Type is private;
with function "=" (Left, Right : Element_Type)
return Boolean is <>;
package Ada.Containers.Vectors is
The meaning of <> in a generic formal function is defined by RM 12.6(10):
If a generic unit has a subprogram_default specified by a box, and the
corresponding actual parameter is omitted, then it is equivalent to an
explicit actual parameter that is a usage name identical to the
defining name of the formal.
So if, as you said in the comments, DAY_OF_WEEK is defined in another package, your instantiation is equivalent to
package HoursWorkedVector is new Ada.Containers.Vectors(Natural, Other_Package.DAY_OF_WEEK, "=");
which doesn't work because the "=" that compares DAY_OF_WEEK values is not visible.
You can include Other_Package."=" in the instantiation, as suggested in a comment. There are at least three ways to make "=" visible, so that your original instantiation would work:
use Other_Package; This will make "=" directly visible, but it will also make everything else defined in that package directly visible. This may not be what you want.
use type Other_Package.DAY_OF_WEEK; This makes all the operators of DAY_OF_WEEK directly visible, including "<", "<=", etc., as well as all the enumeration literals, and any other primitive subprograms of DAY_OF_WEEK that you may have declared in Other_Package. This is probably the favorite solution, unless for some reason it would be a problem to make the enumeration literals visible.
Use a renaming declaration to redefine "=":
function "=" (Left, Right : DAY_OF_WEEK) return Boolean
renames Other_Package."=";
This makes "=" directly visible.
The compiler automatically selects the predefined equality operator:
with
Ada.Containers.Vectors;
package Solution is
type Day_Of_Week is (Work_Day, Holiday);
package Hours_Worked_Vector is
new Ada.Containers.Vectors (Index_Type => Natural,
Element_Type => Day_Of_Week);
end Solution;

Lua throwaway result

I have a situation where I perform some operations on tables, call them T and V. I have set the metatable up correctly and everything works as expected. The issue is that I usually don't need the result of the calculation. So instead of writing
for i=1,5 do
_=T+V
end
is there a way to just have
for i=1,5 do
T+V
end
?
I am not using the Lua commandline so I cannot just write =T+V.
Make a function that does nothing and pass it to it:
function NOP() end
for i=1,5 do
NOP(T+V)
end
This additionally serves to document your intentions, and that the side-effect is what you're after.
Looking at syntax of Lua in extended BNF I don't see an way to construct an expression (exp) without a equal sign or something else.
There are only 4 cases where an expression (exp) can be used:
Assigning a value e.g. p = exp
As condition e.g. while exp then
In a function call i.e. f(exp)
for indexing i.e. t[exp]

How to check if a value is empty in Lua?

What is the proper way to make a conditional which checks of something is or is not empty in Lua? if x == "" and f x ~= "" does not seem to work.
Lua is a dynamically type-based language.
Any variable can hold one of the following types: nil, boolean, number, string, table, function, thread, or userdata.
Any variable in a table (including _G, the table where globals reside) without a value gives a value of nil when indexed. When you set a table variable to nil, it essentially "undeclares" it (removing the entry from memory entirely).
When a local variable is declared, if it is not assigned immediately it is given a value of nil. Unlike table variable, when you set a local variable to nil, it does not "undeclare" it (it just has a value of nil).
In Lua, an empty string ("") is still a "value" - it's simply a string of size zero.
I recently ran across this problem as well. LuaSQL was returning empty strings if a database value was 'blank' (not null). A hacky approach, but here's how I solved it:
if (string.len(x) >= 1) then
...
end
I'm going to make an assumption that the OP means "how do you tell when a variable is unassigned".
Example:
local x
The variable x is "empty", it is initialized to "nil". (Not the text "nil", but an enumerated value that indicates that the variable is unassigned. In Lua that is defined as nil, in some other languages it is defined as NULL.)
Now assign x a value.
Example:
x=""
Now x is not nil.
Another example:
x=0
x is not nil.
Try running this code, it should make the situation clear to you.
local x
if x==nil then print("x is nil") end
x=0
if x==nil then print( "This line won't be written") end
x=""
if x==nil then print( "and this line won't be written") end
The first if statement will evaulate to true and the print statement will be called. The 2nd and 3rd if statements are false and the print statements will not be executed.
In conclusion, use "==nil" to check to see if a variable is "empty" (which is more properly said "nil").
You probably have spaces, newlines or other non-visible characters in your string. So you think it is "empty", but it isn't. This typically happens when you are taking input from the user, and has to type "enter" to finish - the "enter" ends up in the string.
What you need is a function that tells you whether the string is "blank" - either empty, or a list of spaces/tabs/newlines. Here's one way to do it:
function isBlank(x)
return not not tostring(x):find("^%s*$")
end
Usage:
if isBlank(x) then
-- ...
end

Ruby or ROR - arguments of function separated by '||'

I've just encountered an interesting piece of code. I'd like to determine if it's a ruby standard or a rails convention.
redirect_to(session[:return_to] || users_path)
This prevents redirect_to :back from causing errors in some cases. In c++ something like that would mean a function with one bool argument. But here it seems to work another way - it takes that argument which isn't a nil I suppose. Can someone explain it to me and show an example definition of such a function, which takes arguments separated by '||'?
Bye
Boolean operators such as || and && return the last evaluated statement.
An example,
puts "hi" && "no"
The above will print "no" since both strings are considered 'truthy' and "no" was the last value called.
In this case the programmer is taking advantage of the short circuit nature of the || operator. So another example,
puts "hi" || "no"
The above will output "hi" since "hi" is considered truthy and or is short circuited "hi" was the last value called from the expression and will be returned.
You will see this kind of construct a lot in ruby, especially with ifs.
a = if true
"A will be set to this string"
else
"This will never happen"
end
puts a #=> A will be set to this string
Edit: As nick mentioned, it is important to note that only nil and false are treated as "falsy". Some interesting examples
a = nil || "hi"
puts a #=> "hi"
a = false || "hi"
puts a #=> "hi"
In these two cases the first argument is "falsy" so the "hi" is evaluated and returned (and then assigned to a)
a = Object.new || "hi"
puts a #=> <Object:0x10832420>
In this case (and for any other value as the first argument) Object.new is "true" and thus "hi" is never evaluated. In your particular example, the author was most likely testing for the presence (not nil) of session[:return_to]. This can be very useful but always remember that it may not work properly if false is a valid value.
This is called Short-Circuit Evaluation and it is common in many programming languages
In plain English, your statement says
"redirect to session[:return_to] if it is present, if not, redirect to users_path"
It calls redirect_to(session[:return_to]) if session[:return_to] is truthy (e.g. not nil or false).
If session[:return_to] is falsy, then it calls redirect_to(users_path).
See http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators#Logical_Or.
The logical OR is short-circuited, meaning that if the left-hand side is "true", or non-nil, then the value of the entire expression is the left-hand side, and the right-hand side is never considered. So if session[:return_to] is non-nil, it is the value of the expression. If it is nil, though, then the value of the expression is the value of the right-hand side, i.e. the value of user_path.
You can even write things like x || x = "foo", in which case x only gets reassigned if it was nil to begin with, but won't be touched if it is non-nil.
As for the function, it just takes a string, and it doesn't care what you plug in to the argument.

Resources