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

Project multifiles

Started by MrNice, 15 June 2015 - 11:24 AM
MrNice #1
Posted 15 June 2015 - 01:24 PM
Hey i am starting and wanted to knew if there was a way to split program to other files…??
Menu would be alone, and rest of part programs.
Bomb Bloke #2
Posted 15 June 2015 - 03:33 PM
Generally, you'd do this by building APIs. However, IMHO it's only worth doing if you intend to re-use the code you pull out of your main script file in other projects as well.
MrNice #3
Posted 15 June 2015 - 04:20 PM
No the codes goes and goes, so there is no include??
MKlegoman357 #4
Posted 15 June 2015 - 04:40 PM
Bomb Bloke linked you a tutorial which explains how to put your code in separate files and use it.
SquidDev #5
Posted 15 June 2015 - 04:47 PM
I've gotta disagree with BombBloke about only separating code if you plan to reuse it - 2000+ line files are quite hard to edit. I know I've written Howl to handle this, and Oeed's Compilr emulates fs calls so you can package multiple files into one using load/dofile.

If you don't want to publish your code the easiest thing to do is to run the external module with dofile:


--# A.lua
local function myWonderfulFunction()
-- magic
end
return {
  myWonderfulFunction = myWonderfulFunction,
}


--#B.lua
local A = dofile("A.lua")
A.myWonderfulFunction()

But then you might as well use os.loadAPI.
Edited on 15 June 2015 - 02:47 PM
MrNice #6
Posted 15 June 2015 - 04:55 PM
And how do take a part of making storage file, i read about serialize and unserialize but still don't know to make a huge dimensional array… ore are arrays some how multi read….

I mean when i use serialize i got this output..
{
[ 14 ] = "minecraft:stone",
[ 9 ] = "flansmod:flanMWFlashlight",
[ 10 ] = "flansmod:goldDesertEagle",
name = "567",
[ 13 ] = "minecraft:stone",
}{
[ 14 ] = "minecraft:stone",
[ 9 ] = "minecraft:bread",
name = "bgf",
[ 13 ] = "minecraft:stone",
}{
"654",
[ 13 ] = "minecraft:stone",
[ 9 ] = "minecraft:bread",
[ 14 ] = "minecraft:stone",
}{
"432",
recp = "minecraft:stone",
}

but when using writeLine i got it on 1 line and i think it is more clearly…. but not using serialize :/

The problem is how to let know which multi table will be loaded… or would they be connected or what so ever if i got them in one file. Is there any db??

I am trying to store recipes…
Bomb Bloke #7
Posted 16 June 2015 - 02:59 AM
Writing a table:
local myTable = {}  -- Fill this with whatever.
local myFile = fs.open("someFile", "w")
myFile.writeLine(textutils.serialize(myTable))
myFile.close()

Reading a table:
local myFile = fs.open("someFile", "r")
local myTable = textutils.unserialize(myFile.readAll())
myFile.close()

If you want to do multiple tables in one file, it's generally easiest to them all in a single table (as sub-tables) and write that.
MrNice #8
Posted 17 June 2015 - 11:30 AM
The hole idea of this i started to make a db file - "flatcraftsql" my idea is to:

make a global's
array holding all databases (folders)
|-in it:array's holding tables (*.tab files)
|-in this:holding data

Now there was a concept of making for each db/folder shematic table descirbing type of variables
and in other storing a auto increment last value id

If schematic were on we could parse incoming data or convert it even, and id would be usefull 2…
1>)
or try to load all data with a better parser or what so ever… you know
use line:
1,(dataarray)
2,(dataarray)
dataarray contains default varable destobe in schematic or somewhere else if not defined by user

2>)
or
(1,0,nill,x)
(5,1)
(6,xy,true)

Which concept is better??
The Crazy Phoenix #9
Posted 17 June 2015 - 07:12 PM
Or you could simply just make a file which contained the shortest possible decrypting code following by in comments all the file data, maybe indicated by a header that names each file and marks the byte range it can be found at. Would be much simpler. And if you don't need to be un-packable on any system, you can omit the decrypting code and just have a program do that.
MrNice #10
Posted 18 June 2015 - 12:08 PM
Well i was looking around and serilize option fucks data it is not stored in 1 line!!, and text utilitis unserilize dosent work either


--Save table
t = {"1","2","3","4"}
c = {5,6,7,8,c=3}
table.sort(t)
table.sort(c)
hWrite = fs.open("fileName", "w")
hWrite.writeLine(textutils.serialize(t))
hWrite.writeLine(textutils.serialize(c))
hWrite.close()
--Load the table
hRead = fs.open("fileName", "r")
--b={}
local b = (hRead.readAll())
hRead.close()
print(B)/>
data={}
data=textutils.unserialize(B)/>
for key,value in pairs(data) do print("key ",key," value",value) end

it always says that data is nil
so decided to
*.tab files will have 1 tables for all records that i will serialize so the output will be

(
1,datainbase
2,data2inbase
x,y
)

and datainbase will have to be parseout saving table to string/ loading string to table
flaghacker #11
Posted 18 June 2015 - 02:16 PM
Well i was looking around and serilize option fucks data it is not stored in 1 line!!, and text utilitis unserilize dosent work either


--Save table
t = {"1","2","3","4"}
c = {5,6,7,8,c=3}
table.sort(t)
table.sort(c)
hWrite = fs.open("fileName", "w")
hWrite.writeLine(textutils.serialize(t))
hWrite.writeLine(textutils.serialize(c))
hWrite.close()
--Load the table
hRead = fs.open("fileName", "r")
--b={}
local b = (hRead.readAll())
hRead.close()
print(B)/>
data={}
data=textutils.unserialize(B)/>
for key,value in pairs(data) do print("key ",key," value",value) end

it always says that data is nil
so decided to
*.tab files will have 1 tables for all records that i will serialize so the output will be

(
1,datainbase
2,data2inbase
x,y
)

and datainbase will have to be parseout saving table to string/ loading string to table

You can't just paste two serialized tables after each other in a file and expect deserialization to work. I recommend putting them both in one "main" table and (de)serialize that. This should work:

--Create table
local t = {"1","2","3","4"}
local c = {5,6,7,8,c=3}
table.sort(t)
table.sort(c)

--Save table
local main = {t, c}
local hWrite = fs.open("fileName", "w")
hWrite.write(textutils.serialize(main))
hWrite.close()

--Read table
local hRead = fs.open("fileName", "r")
local fileContents = hRead.readAll()
hRead.close()
print(fileContents);
local newMain = textutils.unserialize(fileContents)
newT = newMain[1]
newC = newMain[2]

--Print table
print("t:")
for key,value in pairs(newT) do print(key, ": ", value) end
print("c:")
for key,value in pairs(newC) do print(key, ": ", value) end

Edit: improved code a little bit
Edited on 18 June 2015 - 03:25 PM
Bomb Bloke #12
Posted 18 June 2015 - 02:20 PM
Edit: :ph34r:/>
Edited on 18 June 2015 - 12:20 PM
MrNice #13
Posted 19 June 2015 - 11:34 AM
Well mby you are right but i nee to rework the serilize

This is what i am trying to achieve:

{
{ "1", "2", "3", "4", },
{ 5, 6, 7, 8, c = 3, },
}

and not this
{
{ "1",
"2",
"3",
"4",
},
{
5,
6,
7,
8,
c = 3,
},
}
Bomb Bloke #14
Posted 19 June 2015 - 12:19 PM
This is what i am trying to achieve:

{
{ "1", "2", "3", "4", },
{ 5, 6, 7, 8, c = 3, },
}

Why do you need this exact layout? What's wrong with the methods you've been given? And more to the point, what is it you're really trying to achieve here?

Be careful of falling into the trap of losing sight of your ultimate goal; don't concentrate too hard on doing every single step "a specific way", concentrate on what your final result's going to be.
MrNice #15
Posted 19 June 2015 - 12:49 PM
This seems to work:

fC=textutils.serialize(main)
result = string.gsub(fC, "\n", "") -- remove line breaks
result=string.gsub(result," ","")
result=string.gsub(result,"{{","{\n{")
result=string.gsub(result,"},","},\n")

Out:

{
{"1","2","3","4",},
{5,6,7,8,c=3,},
}

And unserilize work also with no need to change..
The Crazy Phoenix #16
Posted 20 June 2015 - 11:06 AM
If you use %s in the pattern, you can remove all whitespace at the same time. I don't think you need to insert whitespace in between two open brackets or after a close bracket and a comma for it to work.
MrNice #17
Posted 21 June 2015 - 02:57 PM
What the fuck… trying now to test my api going to lua mode loading api, going back to normal computer mode and trying to command db help, then command apis gives me null…
http://pastebin.com/81PWKZvn
Lupus590 #18
Posted 21 June 2015 - 03:35 PM
This is an educated guess here:
The lua interpreter has it's own environment, when you type exit() into the interpreter that environment is discarded and you are left with what was before the interpreter ran.

If your still want to load the API from the interpreter, then you will have to run your program from the interpriter too (use shell.run(programName, arg1,arg2, …, argN) )
Alternatively create a program which loads your API
Edited on 21 June 2015 - 01:35 PM
MrNice #19
Posted 21 June 2015 - 04:25 PM
SO why it gives nill to api command…
Lupus590 #20
Posted 21 June 2015 - 09:32 PM
To understand the cause we need to know about how lua stores global data, a little about enviroments, how the in-game lua program/interpreter works and how the os.loadapi function works:
Global variables are stored in a table known as the global table (aka _G which is the name I will use from now on). The os.loadapi function takes a file path/name, interprets/compiles it into a table and places this table into _G granting access to the API for all programs.

You can change _G and build your own (this is how sandboxes work in ComputerCraft [along with other stuff]), the lua program does this (if my assumption is correct). When you call the program the first thing it does is constructs itself a sandbox by copying _G to another table (lets name it env [short for environment]).
When your API is loaded in the lua program it is loaded into env not _G .It should be noted that when you exit the lua program, that env is deleted and your API is not in _G. It should also be noted that while the lua program is running, _G is ignored and env is used in it's place.

Referring to my earlier solutions (see post #18):
  • Calling your program from the lua program (not calling exit after loading your API) will force your program to use the env table which will have your API loaded from your earlier command input.
  • With the second program solution (I'll call the program which loads your API the Loader, and the other one which you made for testing your API the Tester). Both programs will be using _G, which means that your Loader will put your API into _G, which your Tester will be able to access.
Of course the better solution is to put os.loadapi("myAPI") at the top of every program that will use the API (os.loadapi will not attempt to load it twice).
Edited on 21 June 2015 - 07:34 PM
Bomb Bloke #21
Posted 21 June 2015 - 11:32 PM
When your API is loaded in the lua program it is loaded into env not _G .

os.loadAPI() always places into _G. If you load an API while running the "lua" script, then other scripts will be able to see that API just fine.

At a glance, the linked script may error out on line 11, where it tries to call a function it hasn't bothered to define yet.

If there's more to the issue than that, then explain what command you're using in the Lua console, why you aren't using that command in the script itself, and exactly what error you're getting.
Lupus590 #22
Posted 22 June 2015 - 09:54 AM
When your API is loaded in the lua program it is loaded into env not _G .

os.loadAPI() always places into _G. If you load an API while running the "lua" script, then other scripts will be able to see that API just fine.

What I meant was that the lau program may be using sandboxing, I was trying to explain it simply without redefining _G
If the lua program doesn't use sandboxing (I have no idea, this is based on what I've observed in this post) then I will accept the correction.
MrNice #23
Posted 24 June 2015 - 06:17 PM
I don't have any idea.. i would like to overcome the sql function and how to implement it i mean this part: where id=1 or recpie >5 and not<10. Any pro has an idea??
Bomb Bloke #24
Posted 25 June 2015 - 01:56 AM
I think you're missing more than a bit of context from your question.

What on earth are you talking about?
HPWebcamAble #25
Posted 25 June 2015 - 06:22 AM
What on earth are you talking about?
My thoughts exactly


More specifically…

i would like to overcome the sql function
What is 'the sql function'?

how to implement it i mean this part: where id=1 or recpie >5 and not<10
So id = 1 and 5 < recipe < 10?

What recipe?
How does it have a numerical value? You mean how many items a certain recipe makes?

I think you're missing a bit of context from your question.
MrNice #26
Posted 01 July 2015 - 05:54 PM
Well, it should be useful to make a another table structure to store all database need info like type of data, default and ext in separate table, last auto increment used index -ai, or try to put it in a 0 record in table with data….??
Squiiz with data??
0=>(table structure){key1={string;default value1}}{key2={number;df=10}{id=ai}}

or separate file/table

How can i block access from opening, executing files, seeing them???