saveProjectTab

Ok, so I have searched around in the forum but havent found any answer, so here is the question. I need to save multiplie lines in a tab with saveProjectTab but cant figure out how to continue write lines in it as the new saveProjectTab deletes what I wrote before.
Example:

saveProjectTab("Test","--Hi")
saveProjectTab("Test","--This is a test")

What do I do wrong?!?

Write everything in a table or a string.


function setup()
    tab={}
    table.insert(tab,"--Hi")
    table.insert(tab,"--This is a test")
    str=table.concat(tab,"\
")
    saveProjectTab("test",str)
end

or


function setup()
    str=""
    str=str.."--Hi\
"
    str=str.."--This is a test\
"
    saveProjectTab("test",str)
end

Ok, understanding now, thanks!

A prettier looking way:

saveProjectTab("Test", [[
Hi!
This is a test!
Using two brackets can make a multiple-line string.
And it saves formatting! Use any characters you want except for double-brackets.
And different lines save, too!
]])

@SkyTheCoder Thanks! Looks a little better and easier that way.

Here’s another example of saving data to a tab. Instead of saving everything in a table or a string and then writing that data to the tab at the end of the program, the data can be saved as the program is running. This would also work for debugging a buggy program. Program data could be saved to a tab as the program runs, and when it crashes, the tab would contain any data saved up to that point and could be reviewed. Since “readProjectTab” causes an error and halts the program if the tab doesn’t exist, I use a function to check if the tab exists. If it doesn’t, an empty tab is created.


function setup()
    doesTabExist("test")    
    updateTabData("test","--[[\
this is the first line\
")
    someData()
    someOtherData()
    updateTabData("test","\
this is the last line\
--]]\
")
end

function doesTabExist(tab)    -- check if tab exists
    list=listProjectTabs()
    for a,b in pairs(list) do
        if b==tab then
            return
        end
    end
    saveProjectTab(tab,"")
end

function updateTabData(tab,str)
    data=readProjectTab(tab)    -- read current tab data
    data=data..str            -- add new data to existing data
    saveProjectTab(tab,data)    -- save the tab data
end

function someData()  -- update some data 
    updateTabData("test","\
someFunction\
") 
    for z=1,10 do
        updateTabData("test","the value of z is "..z.."\
")
    end
end

function someOtherData()    -- update some other data
    updateTabData("test","\
someOtherFunction\
") 
    for z=100,110 do
        updateTabData("test","the value of z is "..z.."\
")
    end
end

@dave1707 Similiar to that, a while ago for a project I was working I made a log function, which works like the above program but with much less and more compact code, and can automatically extend the multiple-line comment to fit more text.

function log(msg)
    if tableContains(listProjectTabs(), "log") then
        saveProjectTab("log", string.sub(readProjectTab("log"), 1, string.len(readProjectTab("log")) - 5) .. "\
" .. msg .. "\
--]]")
    else
        saveProjectTab("log", "--[[\
" .. msg .. "\
--]]")
    end
end

@SkyTheCoder That’s what I like about this forum, everyone has a different way of doing the same thing. And because of that, I learn new things and so do the noobs.

Oops, just realized I forgot to include the function tableContains(table, search). Posting in a moment…

Log function and table search function bundled together for easy copying & pasting.

function log(msg)
    if tableContains(listProjectTabs(), "log") then
        saveProjectTab("log", string.sub(readProjectTab("log"), 1, string.len(readProjectTab("log")) - 5) .. "\
" .. msg .. "\
--]]")
    else
        saveProjectTab("log", "--[[\
" .. msg .. "\
--]]")
    end
end

function tableContains(t, f)
    local i = false
    for k, v in pairs(t) do
        if not i then
            if v == f then
                i = true
            end
        else
            break
        end
    end
    return i
end

One thing I forgot to mention: it can add to the previous log, so if you called log(“Hello World!”) in setup, and you ran the project twice, there would be two "Hello World!"s in the log.

@SkyTheCoder To make your routine smaller, here’s another version of tableContains.


function tableContains(t, f)
    for k, v in pairs(t) do
        if v == f then
            return true
        end
    end
    return false
end

@dave1707 Haha, thanks. Returning variables, breaking a while/for loop, and just saying return confuse me on how they would react sometimes.

@SkyTheCoder, you could’ve taken a middle ground:

function tableContains(t, f)
    local i = false
    for k, v in pairs(t) do
        if not i then
            if v == f then
                i = true
                break
            end
        end
    end
    return i
end

Personally, I favor @dave1707 's approach. I see nothing wrong with multiple "return"s–it almost always makes the code shorter, hence easier to understand. Error or unusual situations can be handled up front in the function and then returned from, leaving the bulk of the code to deal with its “normal” purpose without any special-casing or contortion of the code with extra flags. The only trick with multiple returns is to make sure every such “return” returns the expected value–it can be easy to forget.

If you don’t like multiple returns, then this will work also. Since there aren’t a lot of tab in a project, going thu all the tabs even after a match is found won’t slow things down that much.


function tableContains(t, f)
    local i = false
    for k, v in pairs(t) do
        if v == f then
            i = true
        end
    end
    return i
end

@dave1707 In my mind not checking if i already exists or not breaking out of the for loop when i is true lags a bit. But it probably only slows it down by one tenth of a millisecond. :stuck_out_tongue:

@starblue As I said, multiple returns confuse me. :-?


function log(msg)
    local tabExists = function(search) for k, v in pairs(listProjectTabs()) do if v == search then return true end end return false end
    if tabExists("log") then saveProjectTab("log", string.sub(readProjectTab("log"), 1, string.len(readProjectTab("log")) - 5) .. "\
" .. msg .. "\
--]]") else saveProjectTab("log", "--[[\
" .. msg .. "\
--]]") end
end

How’s that for small and compact?

Also, @dave1707, in your function doesTabExist, it creates a global variable “list.” It’s best to make it local.

@TheSkyCoder If you expand out the small and compact code to normal line formatting, it has the same amount of lines as your original code using my double return code. 16 lines of code. Putting a lot of code on one line will make it look smaller, but it also makes it a lot harder to read. If you want small code, see the very last section of code. 10 lines of code.

small and compact code expanded to normal line formatting

function log(msg)
    local tabExists = function(search) 
            for k, v in pairs(listProjectTabs()) do 
                 if v == search then 
                      return true 
                 end 
            end 
            return false 
    end
    if tabExists("log") then 
         saveProjectTab("log", string.sub(readProjectTab("log"),
                1, string.len(readProjectTab("log")) - 5) .. "\
" .. msg .. "\
--]]") 
         else 
                saveProjectTab("log", "--[[\
" .. msg .. "\
--]]") 
     end
end

original code using double return code

function log(msg)
    if tableContains(listProjectTabs(), "log") then
          saveProjectTab("log", string.sub(readProjectTab("log"), 
               1, string.len(readProjectTab("log")) - 5) .. "\
" .. msg .. "\
--]]")
          else
               saveProjectTab("log", "--[[\
" .. msg .. "\
--]]")
    end
end
function tableContains(t, f)
    for k, v in pairs(t) do
        if v == f then
            return true
        end
    end
    return false
end

code rewritten for compactness

function log(msg)
    for k,v in pairs(listProjectTabs()) do
        if v=="log" then
            saveProjectTab("log", string.sub(readProjectTab("log"), 
                 1, string.len(readProjectTab("log")) - 5) .. "\
" .. msg .. "\
--]]")
            return
        end
    end
    saveProjectTab("log", "--[[\
" .. msg .. "\
--]]")
end

@SkyTheCoder Not declaring variables as local seems to be a fault of mine. Sometimes it causes a bug and I waste time tracking down the problem.

@dave1707 The code rewritten for compactness is nice, I didn’t think of that. And the code I posted pushed up all in one line was me wondering if I could trick your brain. :stuck_out_tongue: