Page 1 of 1

[SOLVED]One variable references two different objects simultaneously

Posted: Sat Dec 09, 2023 3:53 am
by abyssol

Code: Select all

if c.next == a then os.exit() end
if c.next == b then os.exit() end
local s = tostring(a) .. "\n" .. tostring(b)
I couldn't believe that the second line is just next to previous line, but c.next can be equal to a and can be equal to b at the same time, though table address is different between a and b (operator meta methods are not defined

I am trying to implement a linked list container. When I use it, this odd thing happened. I checked functions of class List and all behaviors work as expected. I finally found this strange thing outside the functions of class List, in other words, in a block that calls the functions of class List.

Code: Select all

function c:setFront(e)
  self.front = e
  all variables here have correct assigned value
end

function func()
  c:setFront(a)
  if c.front == b then os.exit() end
  if c.getFront() == a then os.exit() end
  local s = tostring(a) .. "\n" .. tostring(b)
end
I have no idea what to do.

Re: One variable references two different objects simultaneously

Posted: Sat Dec 09, 2023 6:06 am
by MrFariator
Can you provide a runnable example? Specifically, what are the values of "a" and "b"?

Re: One variable references two different objects simultaneously

Posted: Sat Dec 09, 2023 10:03 am
by abyssol
MrFariator wrote: Sat Dec 09, 2023 6:06 am Can you provide a runnable example? Specifically, what are the values of "a" and "b"?
My hero, you have appeared.
lovegame.zip
(5.06 KiB) Downloaded 66 times

Re: One variable references two different objects simultaneously

Posted: Sat Dec 09, 2023 11:48 am
by MrFariator
Well, when you launch the project, manager.open is run once in scene.lua. This is presumably the place that you are having your issues in.
I added the following modifications to check what each value was:

Code: Select all

function manager.open(n)
  if not scene[n] then
    manager.load(n)
  end
  list:setBack(scene[n]) -- in setBack() list.back is correct

  -- here list.back can be equal to scene.Game
  -- and can be equal to scene.Setting
  -- simultaneously.
  print(list.front, scene.Game, scene.Setting) 
  if list.front == scene.Game then print("list.front and scene.Game share same value") end
  if list.front == scene.Setting then print("list.front and scene.Setting share same value") end
end
Upon launching the project, list.front has a value ("StartPage" scene I presume), while scene.Game and scene.Setting are both nil.
Then, I clicked the "Start" button on the screen, and then "Setting". This made those if-then-prints I added both launch twice, and both times scene.Game and scene.Setting are nil. As such, whatever your code is doing, it's making list.front, scene.Game and scene.Setting all become nil, which does indeed fulfill the conditions for both if-statements that I added to be true. Nil equals nil is true, after all.

I didn't dig too deep into your code to find what the issue might be, but I presume you are deleting scenes somewhere, and you aren't accounting for this. Whether this is a bug or oversight, you might know better. Without digging further, as a solution, you might want to check if the value of scene.Game or scene.Setting is nil, before checking their value against list.front. For example:

Code: Select all

if scene.Game ~= nil and scene.Game == list.front then 
  -- do things
end
-- alternatively, if you can be sure that scene.Game can never be false (boolean):
if scene.Game and scene.Game == list.front then 
  -- do things
end
Unrelatedly to the issue you are having, I think your List:erase (in list.lua) has a bug in it:

Code: Select all

function List:erase(e)
  if self[1][e] then
    self[2][self[1][e]] = self[2][e]
  elseif e == self.front then
    self.front = self[2][e]
  end
  if self[2][e] then
    self[1][self[2][e]] = self[1][e]
  elseif e == self.back then
    self.back = self[1][e]
  end
  self[1][e] = nil -- error: table index is nil
  self[2][e] = nil
end
I believe your code is not accounting for the possibility that e may be nil. This makes your project crash if I click on some of the menu items displayed. As such, you might want to add some if-guard that makes the code return early.

Re: One variable references two different objects simultaneously

Posted: Sat Dec 09, 2023 12:37 pm
by abyssol
MrFariator wrote: Sat Dec 09, 2023 11:48 am Unrelatedly to the issue you are having, I think your List:erase (in list.lua) has a bug in it:

Code: Select all

function List:erase(e)
  if self[1][e] then
    self[2][self[1][e]] = self[2][e]
  elseif e == self.front then
    self.front = self[2][e]
  end
  if self[2][e] then
    self[1][self[2][e]] = self[1][e]
  elseif e == self.back then
    self.back = self[1][e]
  end
  self[1][e] = nil -- error: table index is nil
  self[2][e] = nil
end
I believe your code is not accounting for the possibility that e may be nil. This makes your project crash if I click on some of the menu items displayed. As such, you might want to add some if-guard that makes the code return early.
I deleted all the extraneous code to make this example simple. There is something i didn't tell you that when you delete manager.close() in /scenes/game.lua, the true strange thing about thread topic will appear

and without this error

Code: Select all

self[1][e] = nil -- error: table index is nil

Re: One variable references two different objects simultaneously

Posted: Sat Dec 09, 2023 1:30 pm
by abyssol
MrFariator wrote: Sat Dec 09, 2023 11:48 am
an example runs like thread topic says
lovegame.zip
(5.14 KiB) Downloaded 69 times
Well, it still seems like an impossible thing :oops:

Re: One variable references two different objects simultaneously

Posted: Sat Dec 09, 2023 2:03 pm
by abyssol
MrFariator wrote: Sat Dec 09, 2023 11:48 am I believe your code is not accounting for the possibility that e may be nil. This makes your project crash if I click on some of the menu items displayed. As such, you might want to add some if-guard that makes the code return early.
Wait, I think of your reply of my previous thread.


It is clear to me now! This function must runs twice (not as expected once

So why conditions can "seems" to be true at the same time

:ultraglee:

Wow, now I have leanred, when troubleshooting, i have to consider how many times the block runs.

You are my hero!