Please login or register.

Login with username, password and session length

 

News:

Welcome to the Updated Lua Forum!


Author Topic: Dirtree: function vs. table?  (Read 139 times)

LuP

  • Regular
  • *
  • Posts: 18
    • View Profile
Dirtree: function vs. table?
« on: July 21, 2010, 03:11:08 am »
Hello,

I have a newbie question. I downloaded Lua code for getting (recursive) list of directory. The slightly modified code looks:

Code: [Select]
require "lfs"

function dirtree(dir, mask)
  assert(dir and dir ~= "", "directory parameter is missing or empty")

  if string.sub(dir, -1) == "/" then
    dir = string.sub(dir, 1, -2)
  end

  local function yieldtree(dir)
    for entry in lfs.dir(dir) do
      if entry ~= "." and entry ~= ".." then

        entry = dir .. "/" .. entry

        if not mask or string.find(entry, mask) then
          coroutine.yield(entry, attr)
        end

        local attr = lfs.attributes(entry)

        if attr.mode == "directory" then yieldtree(entry) end
      end
    end
  end

  return coroutine.wrap(function() yieldtree(dir) end)
end

I get "function" for the result of "dirtree":

Code: [Select]
> a=dirtree(".")
> =type(a)
function

Although I understand the idea of the "dirtree" implementation (I mean I would not be able to program it at the moment, but I understand the majority of steps), I would need to re-implement the function to return "table" (i.e. not "function").

That is, like if I wrote:

Code: [Select]
> a={"a.txt","b.txt"}
> =type(a)
table

Could you help me please with this?

Thank you in advance.

LuP

dirkf

  • Contributor
  • **
  • Posts: 92
    • View Profile
Re: Dirtree: function vs. table?
« Reply #1 on: July 22, 2010, 04:15:34 am »
That function dirtree() is a so-called iterator factory: it creates a function that generates one entry each time it is called. It is usually used in combination with a for-loop.

The easiest way to get what you want, is to create a new function that just calls the old one in a loop and accumulates everything in a table:
Code: [Select]
do
  local old_dirtree = dirtree
  dirtree = function(dir, mask)
    local t = {}
    for entry in old_dirtree(dir, mask) do
      t[#t+1] = entry
    end
    return t
  end
end

The alternative is to modify the dirtree code to not yield each entry but instead store it in table.

LuP

  • Regular
  • *
  • Posts: 18
    • View Profile
Re: Dirtree: function vs. table?
« Reply #2 on: July 22, 2010, 05:07:15 am »
OK, thanks.

I'd still need some explanation:

Why the whole code is enclosed to "do ... end" block? I suppose it is to make the (local) "old-dirtree" variable "really local", that is, it will exist only in the inner "do ... end" scope. Is that right?

If so, why using the "old_dirtree" in the "new dirtree" function is valid? I mean the line "for entry in old_dirtree(dir, mask) do". If I call the (new) "dirtree" function later, i.e. out of outer "do ... end" scope, the "old_dirtree" will be still valid?

And the last question - are the following statements equal?

Code: [Select]
dirtree = function(dir, mask)
end

-- And:

function dirtree(dir, mask)
end

Thank you for patience.

LuP

dirkf

  • Contributor
  • **
  • Posts: 92
    • View Profile
Re: Dirtree: function vs. table?
« Reply #3 on: July 23, 2010, 08:59:41 am »
Why the whole code is enclosed to "do ... end" block? I suppose it is to make the (local) "old-dirtree" variable "really local", that is, it will exist only in the inner "do ... end" scope. Is that right?

Correct.

If so, why using the "old_dirtree" in the "new dirtree" function is valid? I mean the line "for entry in old_dirtree(dir, mask) do". If I call the (new) "dirtree" function later, i.e. out of outer "do ... end" scope, the "old_dirtree" will be still valid?

The magic of closures and lexical scoping  :)

And the last question - are the following statements equal?

Code: [Select]
dirtree = function(dir, mask)
end

-- And:

function dirtree(dir, mask)
end

Yes, they are equivalent. In fact, the latter notation is just syntactic sugar for the former one.

LuP

  • Regular
  • *
  • Posts: 18
    • View Profile
Re: Dirtree: function vs. table?
« Reply #4 on: July 25, 2010, 11:43:05 am »
... Thanks again for the explanation.

Quote
The magic of closures and lexical scoping

I found very similar concept for redefining functions in http://www.lua.org/pil/6.1.html, and some information how closures work.

Quote
Simply put, a closure is a function plus all it needs to access its upvalues correctly.

So "closures" getting a bit revealed for me, magic disappearing...

LuP

dirkf

  • Contributor
  • **
  • Posts: 92
    • View Profile
Re: Dirtree: function vs. table?
« Reply #5 on: July 27, 2010, 12:15:15 pm »
PiL and PiL2 have (of course) an excellent explanation of closures, with lots of examples.
Still, if you come from a background of procedural programming languages, closures can take some time to sink in. See also the Wikipedia article: http://en.wikipedia.org/wiki/Closure_%28computer_science%29

 

+ Quick Reply