[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: lua shell
- From: Bret Victor <bret@...>
- Date: Tue, 25 Apr 2006 09:14:22 +0000 (UTC)
Mildred <ml.mildred593 <at> online.fr> writes:
> I just created a module for lua 5.1.
> It is an interactive shell that can be used with debug.debug() or when
> lua is in interactive mode. Its purpose is to easily know the structure
> of tables.
Oh man, that is hilarious.
I figured that we needed to complete the circle, so I made a little module
that represents the actual filesystem as Lua tables. Now we can use your
shell to cd into actual directories and cat actual files!
--------------------------------------------------------------------------
--
-- "Mounts" the filesystem root in the "files" global. Directories
-- are represented as tables, and files are strings.
--
-- for filename in pairs(files) do print(filename) end
-- local secrets = files.Users.bret["secrets.txt"]
--
--------------------------------------------------------------------------
local lfs = require "lfs"
local yield = coroutine.yield
local dirpaths = {} -- Maps dir proxy table to pathname, and vice-versa.
local dir_mt = {} -- Metatable for dir proxy tables.
local function dirProxy (pathname) -- Make new proxy if one doesn't exist.
local dir = dirpaths[pathname] or setmetatable({}, dir_mt)
dirpaths[dir] = pathname
dirpaths[pathname] = dir
return dir
end
dir_mt.__index = function (t,k) -- Read file or directory.
local pathname = dirpaths[t] .. "/" .. k
local mode = lfs.attributes(pathname,"mode")
if mode == "directory" then return dirProxy(pathname)
elseif mode == "file" then
local file = io.open(pathname)
if not file then return end
local contents = file:read("*a")
file:close()
return contents
end
end
local function dirNext (t) -- Iterate over directory (but don't read files)
local dirpath = dirpaths[t] .. "/"
for filename in lfs.dir(dirpath) do
local pathname = dirpath .. filename
local mode = lfs.attributes(pathname,"mode")
if mode == "file" then yield(filename, "Your data here.")
elseif mode == "directory" then yield(filename, dirProxy(pathname))
end
end
end
-- Let us say a prayer for the __pairs metamethod.
local oldpairs = pairs
local function newpairs (t) -- Override pairs so we can iterate over dirs.
if dirpaths[t] then return coroutine.wrap(dirNext), t, nil end
return oldpairs(t)
end
-- Exports.
files = dirProxy("") -- filesystem root
pairs = newpairs