1
votes

I'm new to Lua and I've just tried to do something that is common and straightforward in other languages but doesn't work the same way in Lua due to parameters to functions being passed by reference (I'm assuming). Also adding things to tables is done by reference too it seems. Pseudo-code:

objImage --stores details about each image like name, iso, aperture etc.
tblMetadata --table that has all the image names and associated data.
tblImages --table to hold the image objects (objImage)

for each line in tblMetadata
  objImage.name = blahblah
  objImage.iso = blahblah
  etc...
  table.insert(tblImages, objImage)
  objImage = nil 
end

In most languages I've used, objImage = nil (or equivalent) resets the object to allow a new image to be added to the table. But in Lua it sets the object just added to the table to nil. What's the technique to add a series of 'objects' to a table in an iterative fashion like this? I tried using a second objImage (objImage2) and assigning objImage to it before adding it (objImage2) to the table, but that just assigns a pointer/reference to the original objImage.

Edit: My pseudo code doesn't fully reflect what I am trying to do, so I've added the actual code below:

function extractExif(tblOutput)
    local tblImages = {}
    local blnFlag = false
    local intCount = 0
    local Image = {}  --pseudo object to hold metadata for each image

    for k,v in pairs(tblOutput) do  --iterate through each value in the table
        if string.find(v, "^=.+") then
            --test if new image other than the first one
            if blnFlag == true then
            --add Image to tblImages and then clear Image object
            table.insert(tblImages, Image)
            Image = nil
            blnFlag = false
            end

            i, j = string.find(v, "/")  -- **** MAC ONLY. Back slash for Windows *****
            Image.filePath = string.sub(v, i)   --returns the file path
            --Image.name = string.match(v, "([^/]+)$")  --return the file name
            blnFlag = true

        elseif string.find(v, "ISO") ~= nil then
            Image.iso = string.match(v, "%a+:(.+)") --get text (i.e value) to right of colon
        elseif string.find(v, "Film") ~= nil then
            Image.filmSim = string.match(v, "%a+:(.+)")
        elseif string.find(v, "Setting") ~= nil then
            Image.drMode = string.match(v, "%a+:(.+)")
        elseif (string.find(v, "Auto") ~= nil) or (string.find(v, "Development") ~= nil) then  -- corresponds to "Auto Dynamic Range" and "Development Dynamic Range" in fuji exif
            Image.dr = string.match(v, "%a+:(.+)")
        else

        end
    end
end

I can of course program this better by using a nested table or the like instead of a flat tblOutput metadata list, and I probably will at some point.

2
is this code correct? what is objTable variable? can you paste some real code? - pkisztelinski
Sorry, that should be objImage. I've corrected it. - erv

2 Answers

3
votes

probably you have to reset objImage using empty table instead of nil value.

for example:

local objImage = {}
local tblMetadata = {'foo', 'bar', 'biz'}
local tblImages = {}

for k, v in ipairs(tblMetadata) do
  objImage.name = v
  objImage.iso = v
  table.insert(tblImages, objImage)
  objImage = {}
end
1
votes
for each line in tblMetadata
  -- Create new LOCAL empty instance
  local objImage = {}
  -- Fill the data
  objImage.name = blahblah
  objImage.iso = blahblah
  etc...
  table.insert(tblImages, objImage)
  -- There is no need for assigning nil to variable objImage
  -- objImage is being garbage-collected automatically as it goes out of scope
end