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

How to easily create, modify and use configs (properly)

Started by jesusthekiller, 19 June 2013 - 08:30 AM
jesusthekiller #1
Posted 19 June 2013 - 10:30 AM
Hi! You probably opened this thread to learn how to make configs for your apps, and, as I promised, it's not hard to do. I assume you know basics on fs api, if you don't it will be a bit harder, not impossible to - fs api is pretty straightforward :)/>

Let's get started!

Most people don't really realize how textutils api powerful is, especially serialize function. We are going to use it.
[right]textutils.serialize() turns table into Lua code.[/right]
We are going to store config in table, we will call it 'config' for this tutorial.

Let's create our config first:

local function saveConfig(table, file)
	-- Open config file in write mode
	-- If failed, create error on level 2, will point to line of code from which function is called
	local fConfig = fs.open(file, "w") or error("Cannot open file "..file, 2)
	
	-- Write serialized table to config file
	fConfig.write(textutils.serialize(table))
	
	-- Save and close file
	fConfig.close()
end

And test it:

saveConfig({1, 2, 3, ['herp'] = 'derp'}, "test")

Output will look like this:

{[1]=1,[2]=2,[3]=3,["herp"]="derp",}

Now, let's load config:

local function loadConfig(file)
	-- Open config file in read mode
	local fConfig = fs.open(file, "r")
	
	-- Read whole file and unserialize it
	local ret = textutils.unserialize(fConfig.readAll())
	
	-- Close file
	fConfig.close()
	
	-- Return table
	return ret
end

Test it:

local config = loadConfig("test")
print(config[1])
print(config[2])
print(config.herp)

Output:

1
2
derp

Full code:

local function saveConfig(table, file)
	-- Open config file in write mode
	-- If failed, create error on level 2, will point to line of code from which function is called
	local fConfig = fs.open(file, "w") or error("Cannot open file "..file, 2)
	
	-- Write serialized table to config file
	fConfig.write(textutils.serialize(table))
	
	-- Save and close file
	fConfig.close()
end

local function loadConfig(file)
	-- Open config file in read mode
	local fConfig = fs.open(file, "r")
	
	-- Read whole file and unserialize it
	local ret = textutils.unserialize(fConfig.readAll())
	
	-- Close file
	fConfig.close()
	
	-- Return table
	return ret
end

saveConfig({1, 2, 3, ['herp'] = 'derp'}, "test")

local config = loadConfig("test")

print(config[1])
print(config[2])
print(config.herp)

So, here you go, configs are easy now!
jesusthekiller #2
Posted 19 June 2013 - 10:51 AM
Code if you want vars in different lines (in file):

local function saveConfig(table, file)
    -- Open config file in write mode
    -- If failed, create error on level 2, will point to line of code from which function is called
    local fConfig = fs.open(file, "w") or error("Cannot open file "..file, 2)
    
    -- Serialize table, add new line chars, write to config file
    fConfig.write(textutils.serialize(table):gsub(",", ",\n"))
    
    -- Save and close file
    fConfig.close()
end

local function loadConfig(file)
    -- Open config file in read mode
    local fConfig = fs.open(file, "r")
    
    -- Read whole file, remove new line chars and unserialize it
    local ret = textutils.unserialize(fConfig.readAll():gsub(",\n", ","))
    
    -- Close file
    fConfig.close()
    
    -- Return table
    return ret
end

saveConfig({1, 2, 3, ['herp'] = 'derp'}, "test")

local config = loadConfig("test")

print(config[1])
print(config[2])
print(config.herp)
ElvishJerricco #3
Posted 19 June 2013 - 11:05 AM
It's hardly "proper" if the only formatting done is a new line for each entry. This and this are things I've built with "pretty" functions whose purposes are to make more readable configs. Tabs and removal of unnecessary characters are the kinds of things you gotta do to make a good looking config.

EDIT: Oh one more thing, textutils.unserialize just does a loadstring("return " .. s)() so you don't have to gsub out the newline characters in the decoder. This even allows you to actually put functions in there. Except they don't have their environments set to anything so they have no access to the normal globals.
theoriginalbit #4
Posted 19 June 2013 - 11:10 AM
It's hardly "proper" if the only formatting done is a new line for each entry. This and this are things I've built with "pretty" functions whose purposes are to make more readable configs. Tabs and removal of unnecessary characters are the kinds of things you gotta do to make a good looking config.
Can't forget ccConfig. :)/>
ElvishJerricco #5
Posted 19 June 2013 - 11:13 AM
Can't forget ccConfig. :)/>/>

Wow I had never seen that but it's pretty nice.
jesusthekiller #6
Posted 19 June 2013 - 11:16 AM
-snip-

By proper I mean: not saving vars to file and calling this file. :D/>

Can't forget ccConfig. :)/>

I know it, made this tutorial for total noobs tho ;)/>
theoriginalbit #7
Posted 19 June 2013 - 11:19 AM
Wow I had never seen that but it's pretty nice.
Thanks :)/>
frostthejack #8
Posted 23 September 2013 - 04:40 AM
im trying to do something kind of like this for a quarry script im writing for redstone in motion. honestly just so i can clean up the code and make it look nicer.

the program i wrote works if im not useing my own functions and just typing out whats required to read and write to files but if i make a function to read and another to save the program doesnt seem to work. it would appear that its not reading the files properly for me
makerimages #9
Posted 23 September 2013 - 10:11 AM
Provide the code to the forum!
Lyqyd #10
Posted 21 October 2013 - 10:49 AM
Moved to Ask a Pro.