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

[SOLVED]loadstring/dostring issues.

Started by MysticPing, 26 September 2014 - 12:43 PM
MysticPing #1
Posted 26 September 2014 - 02:43 PM
So, im using a older version of CC if it helps (tekkit classic) and i have this program which is experiencing a weird issue.

if i do

id, message = rednet.recieve
print(message)

the message is printed (the message is "c1.fuel=100")

Now if i do

message = "return "..message
update = loadstring(message)
update()

It says the line with the "update()" is "attempt to call nil" and the program crashes.
I tried doing this too

dostring(message)

But it was giving me 2 different errors, sometimes it makes the same error as above and sometimes it gives me a indexing error at line 1.

Line 1 is this

c1 = { -- this line.
fuel = 0,
range = true,
currently = "doing nothing"
}

When it comes to normal lua im a pretty experienced coder. But not with CC
Edited on 27 September 2014 - 08:36 AM
Lyqyd #2
Posted 26 September 2014 - 05:36 PM
The first snippet of code wouldn't work at all. Please ensure you've copied the other pieces of code completely correctly, or better yet, post your whole code via copy and paste or pastebin upload.

Loadstring returns either a function or nil, but also an error message when the string can't be loaded. Try printing the error:


local func, err = loadstring(message)
if not func then error(err) end
MysticPing #3
Posted 26 September 2014 - 06:03 PM
Thers no put or get commands in this version of CC. From what i can tell the first snippet is missing a "()". My error here, that does not exist in the code.
The problem is when i print the message it shows, but when i try to loadstring it and run the function it acts as if i-m running a non-existant function. (Therefore the attempt to call nil)
Lyqyd #4
Posted 26 September 2014 - 06:28 PM
Yes, because loadstring is returning nil and an error message. That's why I wanted you to add a variable to your loadstring line to catch the error, and then add the if statement after it to check if it returned anything useful and print the error message if it didn't.
MysticPing #5
Posted 26 September 2014 - 08:08 PM
startup:42: startup:41: [string "string"]:1:
'<eof>' expected

Is what i got.

This is the last few lines (Cause of the issue)

(normally use a pc, this is my school mac)
MKlegoman357 #6
Posted 26 September 2014 - 08:33 PM
The cause of the issue is that the message is not a correct Lua code that is being sent to the program. What message are you sending?
MysticPing #7
Posted 26 September 2014 - 08:39 PM
"c1.fuel=100"
(i was just testing rednet before actually creating my miners)
minecraftwarlock #8
Posted 26 September 2014 - 09:09 PM
message = "return "..message
update = loadstring(message)
update()

I believe the error is caused by this line:

message = "return "..message
MysticPing #9
Posted 27 September 2014 - 07:44 AM
thats why i tried just doing "dostring(message)" (witout the return) and it still errorred.
If i do the loadstring without the return it says index error on line 1, as mentioned above
Edited on 27 September 2014 - 05:45 AM
Bomb Bloke #10
Posted 27 September 2014 - 07:55 AM
An "'<eof>' expected" error is usually caused by placing code after an "end" statement which isn't attached to a block within your script (thus Lua takes it to mean that indicates the end of the script; that is to say, that point should be the end of the script file and nothing more should come after it).

Mismatched end statements usually come about due to incorrect indentation. As has been mentioned, posting the full code may be helpful if you can't see the problem yourself.
MysticPing #11
Posted 27 September 2014 - 08:10 AM
I cannot post the whole code, this is a older version before put and get. And the error only happens when i send a rednet message and try to read it.

I know what a eof error is, but it makes no sense here

EDIT: Even without the return being added it still makes the same error. i
Edited on 27 September 2014 - 06:22 AM
Bomb Bloke #12
Posted 27 September 2014 - 08:52 AM
You don't require the pastebin access within ComputerCraft. The files stored on the computers in your world are accessible via the computers folder in your MineCraft world save.

Messing around with loadstring() myself, I notice that the functions it generates do not share the same environment as the rest of your script. That means that if you define a table as local to that script, then try to loadfile() some code which works within that table, you'll likely get an "attempt to index nil" error. If you define a local function and attempt to loadfile() some code which calls it, that'd generate an "attempt to call nil" error.

You can get around that by changing the environment of the function, eg:

local myTable = {}
local myFunction = loadstring("myTable.myString = \"asdf\"")
setfenv(myFunction, getfenv())
myFunction()
print(myTable.myString)

Another point that's worth keeping in mind is that if your loadstring()'d code errors out when you execute it, odds are the line number you'll be given will be referring to the first line of that string (which can potentially contain line breaks).
Dragon53535 #13
Posted 27 September 2014 - 08:53 AM
I cannot post the whole code, this is a older version before put and get. And the error only happens when i send a rednet message and try to read it.

I know what a eof error is, but it makes no sense here

EDIT: Even without the return being added it still makes the same error. i
While there is no lazy way to post code you can still take the time to write it out or even copy and paste it into code tags [.code][./code] without the .'s.
Now onto your code being problematic, if you add the word return, then it's messing up because it's going to try and return a value you're setting. Basically there you're trying to say return 5 = 5, (which would probably become return true), which would cause a problem as the next line would need an end since you're trying to execute a return without an end afterwards. Now without adding return you say it adds the same problem still, which confuses me, however perhaps c1.fuel is invalid? You say you're on tekkit classic right? i'll attempt to test the code being sent, and trying to find what's the problem.

EDIT: I think i may of gotten ninja'd by someone more experienced than i… Well this sucks good job though Bomb Bloke, lets hope that solves his problem, i'll still test it :P/>

EDIT2: Oh god the old creative menu… Errored myfunction is '<name>' expected wut?
Edited on 27 September 2014 - 07:05 AM
MysticPing #14
Posted 27 September 2014 - 09:05 AM
I tried the setfenv() method several times but it never worked, then i tried it again and it runs now! (also removed the return part!) Thanks people! Awesome!
MKlegoman357 #15
Posted 27 September 2014 - 03:04 PM
"c1.fuel=100"
(i was just testing rednet before actually creating my miners)

Well, from when does this:


return c1.fuel=100

..count as valid Lua code? This is not C++!

-snip-

A function's environment doesn't hold it's local values, so your code wouldn't work.

…Basically there you're trying to say return 5 = 5, (which would probably become return true), which would cause a problem as the next line would need an end since you're trying to execute a return without an end afterwards.

= is the assignment operator, == is the equality operator. Also, a return statement doesn't need an end.

I tried the setfenv() method several times but it never worked, then i tried it again and it runs now! (also removed the return part!) Thanks people! Awesome!

It probably works because your table is not local (which is a bad habit). Don't forget that if you are playing on a server anyone could send malicious code to your computer. Be Aware!

EDIT: I just wanted to point out all mistakes so other people wouldn't think all of these statements are true. Please don't take this too roughly.
Edited on 27 September 2014 - 01:08 PM
Bomb Bloke #16
Posted 27 September 2014 - 03:49 PM
A function's environment doesn't hold it's local values, so your code wouldn't work.

Indeed, I didn't mess around enough. My sample had been built in the Lua console, so I hadn't used a local version of myTable (as I assume you guessed).

I see that user scripts have their own environment, but this is the same for all user scripts running on the system and contains only shell, multishell, and any globals declared by such user scripts.

What I don't see is how you'd get the environment table containing a function's own local variables.
Edited on 27 September 2014 - 02:27 PM
MKlegoman357 #17
Posted 27 September 2014 - 04:52 PM
What I don't see is how you'd get the environment table containing a function's own local variables.

You can get local variables using debug.getLocal or, probably, via Lua bytecode. I don't think there is a way to get all locals of a function.