Day9 自订开机执行的程序码 - 函数宣告与语法糖

前面几天,我探索了 Lua 的变数型别、条件判断、回圈、标准函式库等
在这过程中,我已经多少看过函数定义和使用了
就算没学过,看多了总会模仿阿

今天我就来正式的研究 Lua 函数怎麽写
主题则是,自定义 CC: Tweaked 电脑开机时执行的程序码!
之前我一直在研究开机时自动执行的 motd.lua
这次我想要让电脑执行自己写的 Lua 程序
挖掘开始!

CC: Tweaked 电脑是如何让 startup.lua 自动执行?

首先,我已经知道开机时会自动执行 startup.lua
从这个线索往上溯源,可以找到 /rom/programs/shell.lua #591 有这一行

shell.run("/rom/startup.lua")

再继续往上东翻西找,可以找到 /rom/bios.lua #977 有 Run the shell
这部分先不深入
但可以看出 startup.lua 被自动执行的脉络

/rom/startup.lua 理论上是不能修改的,那我要怎麽自定义呢?
我东翻西找 startup 关键字,先看到 bios.lua #864 有这一段

-- Set default settings
settings.define("shell.allow_startup", {
    default = true,
    description = "Run startup files when the computer turns on.",
    type = "boolean",
})
settings.define("shell.allow_disk_startup", {
    default = commands == nil,
    description = "Run startup files from disk drives when the computer turns on.",
    type = "boolean",
})

看来就是设定是否允许跑 startup
接着搜寻 allow_startupallow_disk_startup
可以看到 startup.lua #161 有这一段 Run the user created startup

-- Run the user created startup, either from disk drives or the root
local tUserStartups = nil
if settings.get("shell.allow_startup") then
    tUserStartups = findStartups("/")
end
---------- 略 ----------
if tUserStartups then
    for _, v in pairs(tUserStartups) do
        shell.run(v)
    end
end

答案呼之欲出了!我相信上面这一段有我要的东西~

Lua 函数定义,function 也是变数

来看看 findStartups 的函数定义

local function findStartups(sBaseDir)
    local tStartups = nil
    local sBasePath = "/" .. fs.combine(sBaseDir, "startup")
    local sStartupNode = shell.resolveProgram(sBasePath)
    if sStartupNode then
        tStartups = { sStartupNode }
    end
    -- It's possible that there is a startup directory and a startup.lua file, so this has to be
    -- executed even if a file has already been found.
    if fs.isDir(sBasePath) then
        if tStartups == nil then
            tStartups = {}
        end
        for _, v in pairs(fs.list(sBasePath)) do
            local sPath = "/" .. fs.combine(sBasePath, v)
            if not fs.isDir(sPath) then
                tStartups[#tStartups + 1] = sPath
            end
        end
    end
    return tStartups
end

这样的函数定义,似乎跟其他语言大同小异,没什麽好说的 ....
是这样吗?!
事实上,function 在 lua 世界里面也是变数,型别就是 function!
如果忘记了,可以复习一下 Lua 变数型别与宣告

Lua 语法糖

事实上,大家所看到的上面这一段宣告,只是 Lua 的语法糖

function findStartups(sBaseDir)
end

它原本的写法是这样

findStartups = function (sBaseDir)
end

如果再继续找 shell.resolveProgram() 会看到 command:find("/")
这也是 Lua 的语法糖
原本的写法是

string.find(command, "/")

还有一种写法,我感到很陌生旁徨@@... 一时之间没有了解,先笔记下来

string["find"](command, "/")

宣告区域变数/函数

至於 local 则是限制这个变数的存取范围
以上述为例,在 startup.lua 宣告 local,就是只能在 startup.lua 使用
否则任何地方都可以使用,这就是 Lua 的语言特性
任何变数没有宣告 local 都是全域变数

自定义开机 startup script

回到一开始我想解决的问题,自定义开机程序
shell.resolveProgram(sBasePath) 会去找到 /startup.lua 和 /rom/startup.lua
所以只要自己新增 /startup.lua 即可在开机时自动执行
如果想要一次跑多个 Lua 程序档
也可以新增多个档案在 /startup/ 资料夹底下

今天先挖矿到这,下次我预计仍是会继续研究 function


<<:  Day 10 - SELECT INTO !

>>:  Day-12 Multilevel Cache

Day 17 - SVG 使用

唷呼~各位看官们今天最後一天上班日,明天就要放中秋连假了,欢呼吧,各位!下班後要搭乘大众运输返乡的...

[day-30] 从U-net 学到了什麽

心得 这次的铁人赛又完赛了,想起第一次参加,学习自己不熟的东西,每天都要实作,实作到最後竟然断赛了,...

110/13 - 把照片储存在Pictures/应用程序名称资料夹 - 3

各位铁人\教师节快乐/ 昨天在显示图片的部份卡关,原本打算用contentResolver.inse...

Day 4 - Object 物件组合技

前言 前两天讲完了一些常用的 Array 组合技,今天来介绍一下它的青梅竹马(?) - Object...

D30 - Python入门挑战end?!

铁人赛只有30天该高兴还是觉得累 哈哈哈 总之顺利度过了 这次的课程进度走一个没很紧绷 但是也是有顺...