Lua not not the same as not not - lua

I was using some coroutines and was trying to resume one using not:
if not co == nil then `resume end
and the coroutine wouldn't resume. Though co was nil. It was baffling.
So I eventually tried
if co then `resume end
and it worked!
why isn't not (nil == nil), which is logically false when co is nil and true when it is not which is not the same as as nil which is logically false when co is nil and true otherwise?
I use not all the time to negate the logical expression but now I'm worried that maybe some of my code is buggy. Maybe this only has a problem with coroutines? (and I'm 100% sure that the value is nil, because that is what is printed out, unless nil no longer equals nil)

not co == nil is equivalent to (not co) == nil because of operator precedence.
If co is nil, then not co is true and so different from nil.
In fact, the result of not is always true or false, and so never equal to nil.
Write not (co == nil) or co ~= nil.

Related

redis script check if hash field exists

The question is about lua script in redis.
I'm trying to check if some field exists in a hash table, but the return value of redis.call suprised me:
EVAL 'local label = "oooo"; local tesid = redis.call("HGET", "nosuchkey", "nosuchfield"); if tesid == nil then label="aaaa" elseif tesid == "" then label="bbbb" else label = "kkkk" end; return {tesid,label}' 0
the return value is
1) (nil)
2) "kkkk"
I don't understand why I got into that else branch -- where label is set to "kkkk" -- when tesid is nil, I think it should output "aaaa".
Why does the script go into "kkkk" label?
For better reading, I paste the script here:
local label = "oooo"
local tesid = redis.call("HGET", "nosuchkey", "nosuchfield")
if tesid == nil
then
label="aaaa"
elseif tesid == ""
then
label="bbbb"
else
label = "kkkk"
end
return {tesid,label}
Short Answer: tesid is false NOT nil.
Redis' conversion rules for nil reply is as follows:
Redis nil reply is converted to Lua false boolean type.
Lua false boolean type is converted to Redis' nil reply.
In your case, HGET returns nil, which is converted to false. So tesid is false. It's not equal to either nil or "", so label is set to kkk. When your code returns tesid as part of the return value, it's converted to Redis' nil reply. And that's why you got {nil, kkk}

Roblox Error: Expected ')' to close '(' at column 3), got '='

Hi I am a user on Roblox and I am trying to script a light switch that turns off 4 lights and I am having a error (it's in the title)
There are 2 blocks being used, the Off4 and On4 switch.
My code is
function OnClicked()
if (workspace.LivingRoomLight.SpotLight.Enabled == true) and (workspace.LivingRoomLight2.SpotLight.Enabled == true) and (workspace.LivingRoomLight3.SpotLight.Enabled == true) and (workspace.LivingRoomLight4.SpotLight.Enabled == true) then
(workspace.LivingRoomLight.SpotLight.Enabled = false) and (workspace.LivingRoomLight2.SpotLight.Enabled == false) and (workspace.LivingRoomLight3.SpotLight.Enabled == false) and (workspace.LivingRoomLight3.SpotLight.Enabled == false)
script.Parent.Transparency = 1
workspace.Off4.Transparency = 0
end
end
script.Parent.ClickDetector.MouseClick:connect(OnClicked)
The other scripts (that work) I use in the ones that use only one light is
function OnClicked()
if (workspace.Hallwaylight.SpotLight.Enabled == true) then
workspace.Hallwaylight.SpotLight.Enabled = false
script.Parent.Transparency = 1
workspace.Off.Transparency = 0
end
end
script.Parent.ClickDetector.MouseClick:connect(OnClicked)
Note: I am only using the on scripts because that's the only one I edited for the one with the error. The error in the on script is the first = at column 3 and when I use '==' instead of '=' then the whole line becomes a error
Try this:
if (workspace.LivingRoomLight.SpotLight.Enabled == true) and (workspace.LivingRoomLight2.SpotLight.Enabled == true) and (workspace.LivingRoomLight3.SpotLight.Enabled == true) and (workspace.LivingRoomLight4.SpotLight.Enabled == true) then
workspace.LivingRoomLight.SpotLight.Enabled = false
workspace.LivingRoomLight2.SpotLight.Enabled = false
workspace.LivingRoomLight3.SpotLight.Enabled = false
workspace.LivingRoomLight4.SpotLight.Enabled = false
...
Some pointers:
x == y means “does x equal y?”. It’s a condition (either true or false).
x = y means “set x to y”. It’s a statement (a command to your program to modify the value of x).
and is an operator that expects conditions to its left and right.
Your program is of the form
if (these four values are true) then
set each of them to false
end
so you need and and == on the first line, but they don’t make sense inside the if — you need four simple statements using =, there.
You don’t really need == though. Comparing boolean values (like workspace.LivingRoomLight.SpotLight.Enabled, which are already true or false) to true is a bit silly: instead of if x == true then ... end it’s nicer to just write if x then ... end.

Ruby - loop to check if at least one pair of values are populated

So in my rails form there are several rows of 2 textfields. For the form to save ok, at least one of the pair of textfields needs to be filled out.
So
nil nil
10 20
nil nil
nil nil
is valid.
This:
nil nil
nil nil
nil nil
nil nil
is invalid
This:
nil 10
nil nil
nil nil
nil nil
is invalid
Here is the method I am using to check all the fields (note that single_field and aggregate_field are strings and are the field names):
def no_values_present?(single_field, aggregate_field)
self.lo_item.lo_line_items.each do |item|
return false if "!item.#{single_field}".nil? && "!item.#{aggregate_field}".nil?
end
true
end
But I guess this doesn't work as it will return true or false several times and will determine that a row is invalid even though a previous row may have been valid.
I need an overall true or false.
How can this be achieved?
Try leveraging any? or none? from the Enumerable module.
Your code could be rewritten as
def no_values_present?(single_field, aggregate_field)
self.lo_item.lo_line_items.none? { |item|
!(item.send(single_field).nil?) && !(item.send(aggregate_field).nil?)
}
end
although I think that it would be clearer to have the condition be positive and to return true when there is a match found. I would write
def any_pairs_present?(single_field, aggregate_field)
self.lo_item.lo_line_items.any? { |item|
!(item.send(single_field).nil?) && !(item.send(aggregate_field).nil?)
}
end
Note that "!item.#{single_field}" will never be nil because it will always be a string! If you want to access instance fields dynamically then one way to do that is with send, but for other options you could look here which suggests the alternatives of instance_eval and instance_variable_get.
The function looks ok, but there seems to be syntax errors, I'd also make a few amendments:
def form_valid?(single_field, aggregate_field)
self.lo_item.lo_line_items.each do |item|
return true if !item.send(single_field).nil? && !item.send(aggregate_field)
end
false
end

Can't use where on a column with nil value

I have an Article model
Article.last.publish
=> nil
Article.last.publish != true
=> true
Article.where("publish != ?", true)
=> []
Why am I getting an empty array there?
There are only 2 falsy values in ruby : false and nil
So, if you check the value of !nil then the output will be true
So with your first statement
Article.last.publish # its output is nil
Then your second statement
Article.last.publish != true # this is correct , since !nil = true
But the last one
Article.where("publish != ?", true)
gets converted into a query as
SELECT `articles`.* FROM `articles` WHERE (publish != 1)
which means all articles whose publish value is not true, which means false
and false is not equal to nil.
nil and false are two different falsy values.
Try Article.where(publish: false)

Lua unpack bug?

I Have stumbled on a weird behavior in Lua unpack function
table1 = {true, nil, true, false, nil, true, nil}
table2 = {true, false, nil, false, nil, true, nil}
a1,b1,c1,d1,e1,f1,g1 = unpack( table1 )
print ("table1:",a1,b1,c1,d1,e1,f1,g1)
a2,b2,c2,d2,e2,f2,g2 = unpack( table2 )
print ("table2:",a2,b2,c2,d2,e2,f2,g2)
Output:
table1: true nil true false nil nil nil
table2: true false nil nil nil nil nil
The second unpack delivers parameters up to the first nil value. I could live with that.
The first table delivers 4? parameters with one being nil in the middle. It has 4 parameters that are not nil, but they aren't the one that are shown.
Could anyone explain this?
This was tried with codepad.org and lua 5.1
The problem can be resolved simply by specifying the beginning and ending indexes to unpack() and using the table.maxn() as the ending index:
table1 = {true, nil, true, false, nil, true, nil}
a1,b1,c1,d1,e1,f1,g1 = unpack( table1, 1, table.maxn(table1) )
print ("table1:",a1,b1,c1,d1,e1,f1,g1)
-->table1: true nil true false nil true nil
The true reason for the discrepancy on how the two tables are handled is in the logic of determining the length of the array portion of the table.
The luaB_unpack() function uses luaL_getn() which is defined in terms of lua_objlen() which calls luaH_getn() for tables. The luaH_getn() looks at the last position of the array, and if it is nil performs a binary search for a boundary in the table ("such that t[i] is non-nil and t[i+1] is nil"). The binary search for the end of the array is the reason that table1 is handled differently then table2.
This should only be an issue if the last entry in the array is nil.
From Programming in Lua (pg.16) (You should buy this book.):
When an array has holes--nil elements inside it--the length operator may assume any of these nil elements as the end marker. Therefore, you should avoid using the length operator on arrays that may contain holes.
The unpack() is using the length operator lua_objlen(), which "may assume any of [the] nil elements as the end" of the array.
2.2 - Values and Types
[...]
The type table implements associative
arrays, that is, arrays that can be
indexed not only with numbers, but
with any value (except nil). Tables
can be heterogeneous; that is, they
can contain values of all types
(except nil). [...]
Given nil to an entry will break the table enumeration and your variables wont be init properly.
Here is a simple example that demonstrates a problematic behavior:
table1 = {true, false, nil, false, nil, true, nil}
for k,v in ipairs(table1) do
print(k, v)
end
output:
1 true
2 false
>Exit code: 0

Resources