This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
moomoomoo3O9's profile picture

string colon operator problem

Started by moomoomoo3O9, 30 June 2015 - 02:45 AM
moomoomoo3O9 #1
Posted 30 June 2015 - 04:45 AM
So, I posted about this issue I was having a while ago, and I finally narrowed down the problem, but before I definitively call it a bug, I want to make sure this behavior is unintended.

If you have two files as so:

file1:
function string.blah(str) return str:upper() end

file2:
shell.run"file1"
print(string.blah("hi"))
print(("bye"):upper())
print(("bye"):blah())

When running file2, it will print HI, then BYE and then give an attempt to call nil error on line 4.
Is this a bug?

Edit: It gets no error in the emulator mimic, interestingly enough, but it errors in-game.
Edited on 30 June 2015 - 02:50 AM
Bomb Bloke #2
Posted 30 June 2015 - 06:20 AM
Certainly looks like a bug to me, but I don't see why you feel you need two files to demonstrate it.
Quintuple Agent #3
Posted 30 June 2015 - 06:54 AM
Ok, well I found something strange to go along with this.
Using the code
Spoiler

local test="testing"
test2="Terst'n"
oldUp = string.upper
print(string.upper(test))
print(test:upper())
print(string.upper(test2))
print(test2:upper())
function string.upper() return "Ya done messed up" end
print(string.upper(test))
print(test:upper())
print(string.upper(test2))
print(test2:upper())
string.upper = function () return "Still messed up" end
print(string.upper(test))
print(test:upper())
print(string.upper(test2))
print(test2:upper())

Used it just to test everything that could mess up, When used in both ccemu and ingame it runs as expected the first time and returns
Spoiler

TESTING
TESTING
TERST'N
TERST'N
Ya done messed up
Ya done messed up
Ya done messed up
Ya done messed up
Sill messed up
Sill messed up
Sill messed up
Sill messed up

However, when ran another time after the computer has been restarted it returns
Spoiler

TESTING
Sill messed up
TERST'N
Sill messed up
Ya done messed up
Sill messed up
Ya done messed up
Sill messed up
Sill messed up
Sill messed up
Sill messed up
Sill messed up

The strVar:upper is still being overwritten
When tested on a different computer without the script on it
string.upper works as it should however strVar:upper() returns "Sill messed up"
so it is being overwritten on the entire ComputerCraft global table
Edit: In 1 of my 6 test strVar:upper() was not overwritten on the other computer, however all other tests had the effect.
Edit2: So as I have tested it appears to work with only upper, I have also tested rep and lower and it does not affect the environment of other computers nor does it change strVar:rep() / strVar:lower() at all
Edit3: A video to prove I am not insane
Edited on 30 June 2015 - 05:55 AM
MKlegoman357 #4
Posted 30 June 2015 - 08:52 AM
The problem here is that the string metatable is shared between computer, because they are all running in the same LuaVM. When you first load the world the first computer to boot up ends up with the original "string" table, while all other computers get a copy of the string API. That's why you can change the functions the first time but not later.

Because of how CC is setup you'll have to leave the strings alone, so no overrides here, nor additions :(/>
moomoomoo3O9 #5
Posted 30 June 2015 - 04:17 PM
Ok, well I found something strange to go along with this.
Using the code
Spoiler

local test="testing"
test2="Terst'n"
oldUp = string.upper
print(string.upper(test))
print(test:upper())
print(string.upper(test2))
print(test2:upper())
function string.upper() return "Ya done messed up" end
print(string.upper(test))
print(test:upper())
print(string.upper(test2))
print(test2:upper())
string.upper = function () return "Still messed up" end
print(string.upper(test))
print(test:upper())
print(string.upper(test2))
print(test2:upper())

Used it just to test everything that could mess up, When used in both ccemu and ingame it runs as expected the first time and returns
Spoiler

TESTING
TESTING
TERST'N
TERST'N
Ya done messed up
Ya done messed up
Ya done messed up
Ya done messed up
Sill messed up
Sill messed up
Sill messed up
Sill messed up

However, when ran another time after the computer has been restarted it returns
Spoiler

TESTING
Sill messed up
TERST'N
Sill messed up
Ya done messed up
Sill messed up
Ya done messed up
Sill messed up
Sill messed up
Sill messed up
Sill messed up
Sill messed up

The strVar:upper is still being overwritten
When tested on a different computer without the script on it
string.upper works as it should however strVar:upper() returns "Sill messed up"
so it is being overwritten on the entire ComputerCraft global table
Edit: In 1 of my 6 test strVar:upper() was not overwritten on the other computer, however all other tests had the effect.
Edit2: So as I have tested it appears to work with only upper, I have also tested rep and lower and it does not affect the environment of other computers nor does it change strVar:rep() / strVar:lower() at all
Edit3: A video to prove I am not insane
What blows my mind is that "a.upper()" worked. That should never work in Lua! This is some very weird behavior…

Should I post a new thread over in bug reports about this? (Even with mk's response above, a.upper() is a behavior that just…shouldn't happen. ("string").upper() should error every time; strings aren't tables, and Quintuple didn't change the string metatable!)
Edited on 30 June 2015 - 02:22 PM
Lyqyd #6
Posted 30 June 2015 - 05:43 PM
No, that shouldn't error. Please see the relevant section of the Lua Reference Manual.
moomoomoo3O9 #7
Posted 01 July 2015 - 03:41 AM
No, that shouldn't error. Please see the relevant section of the Lua Reference Manual.
I'd agree with you if it was ("exampleString"):upper(), but ("exampleString").upper() shouldn't work, from what I've seen. I've never seen the dot operator work with strings, but perhaps I just have more to learn. :P/>

To my knowledge, what should work is as follows:
("wot"):upper() (which is the same as string.upper("wot"))
but, what worked due to the bug was:
("wot").upper() (which is the same as ("wot")["upper"]() It's actually the same as string.upper(nil))


I don't see how ("wot") has an "upper" index.
Edited on 01 July 2015 - 01:58 AM
MKlegoman357 #8
Posted 01 July 2015 - 01:03 PM
I'd agree with you if it was ("exampleString"):upper(), but ("exampleString").upper() shouldn't work, from what I've seen. I've never seen the dot operator work with strings, but perhaps I just have more to learn. :P/>

To my knowledge, what should work is as follows:
("wot"):upper() (which is the same as string.upper("wot"))
but, what worked due to the bug was:
("wot").upper() (which is the same as ("wot")["upper"]() It's actually the same as string.upper(nil))


I don't see how ("wot") has an "upper" index.

You have to remember that strings are similar to tables because:

  1. they can be indexed
  2. you can access it's metatable

You can index strings however you want. For example, this works:


local str = "a string"
local er = "er"

print( str["upp" .. er](str) ) --> A STRING

local a = str[ {"this is a table"} ]

print( a ) --> nil