【问题标题】:How to split a Torch class into several files in a Lua rock如何在 Lua 岩石中将 Torch 类拆分为多个文件
【发布时间】:2016-08-09 04:48:43
【问题描述】:

在我最近协助开发 Torch 的 Dataframe 包时。由于代码库迅速翻了一番,因此需要将课程分成几个部分,以便更好地组织和跟进 (issue #8)。

一个简单的测试类应该是测试包根文件夹中的 test.lua 文件:

test = torch.class('test')
function test:__init()
  self.data = {}
end

function test:a()
  print("a")
end

function test:b()
  print("b")
end

现在对此的 Rockspec 将是:

package = "torch-test"
 version = "0.1-1"
 source = {
    url = "..."
 }
 description = {
    summary = "A test class",
    detailed = [[
       Just an example
    ]],
    license = "MIT/X11",
    maintainer = "Jon Doe"
 }
 dependencies = {
    "lua ~> 5.1",
    "torch >= 7.0",
 }
 build = {
  type = 'builtin',
  modules = {
      ["test"] = 'test.lua',
  }
 }

【问题讨论】:

    标签: lua torch luarocks


    【解决方案1】:

    为了让多个文件为单个类工作,有必要返回最初创建的类对象并将其传递给子部分。上面的例子可以放入文件结构中:

    \init.lua
    \main.lua
    \test-0.1-1.rockspec
    \Extensions\a.lua
    \Extensions\b.lua
    

    luarocks install/make 根据 'require' 语法复制文件,其中每个 . 表示一个目录,而 .lua 被省略,即我们需要将 rockspec 更改为:

    package = "torch-test"
     version = "0.1-1"
     source = {
        url = "..."
     }
     description = {
        summary = "A test class",
        detailed = [[
           Just an example
        ]],
        license = "MIT/X11",
        maintainer = "Jon Doe"
     }
     dependencies = {
        "lua ~> 5.1",
        "torch >= 7.0",
     }
     build = {
      type = 'builtin',
      modules = {
          ["test.init"] = 'init.lua',
          ["test.main"] = 'main.lua',
          ["test.Extensions.a"] = 'a.lua',
          ["test.Extensions.b"] = 'b.lua'
        }
      }
    

    因此,上面将创建一个 test 文件夹,其中包与文件和子目录一起驻留。类初始化现在驻留在返回类对象的init.lua 中:

    test = torch.class('test')
    function test:__init()
      self.data = {}
    end
    return test
    

    子类文件现在需要获取使用loadfile() 传递的类对象(参见下面的init.lua 文件)。 a.lua 现在应该如下所示:

    local params = {...}
    local test = params[1]
    function test:a()
      print("a")
    end
    

    b.lua 的类似补充:

    local params = {...}
    local test = params[1]
    function test:b()
      print("b")
    end
    

    为了将所有内容粘合在一起,我们有init.lua 文件。以下内容可能有点过于复杂,但可以解决:

    • 找到所有可用的扩展并加载它们(注意:需要lua filesystem,您应该将其添加到rockspec,并且您仍然需要将每个文件添加到rockspec,否则它将不在扩展文件夹)
    • 标识路径文件夹
    • 加载 main.lua
    • 在没有安装软件包的纯测试环境中工作

    init.lua的代码:

    require 'lfs'
    
    local file_exists = function(name)
       local f=io.open(name,"r")
       if f~=nil then io.close(f) return true else return false end
    end
    
    -- If we're in development mode the default path should be the current
    local test_path = "./?.lua"
    local search_4_file = "Extensions/load_batch"
    if (not file_exists(string.gsub(test_path, "?", search_4_file))) then
      -- split all paths according to ;
      for path in string.gmatch(package.path, "[^;]+;") do
        -- remove trailing ;
        path = string.sub(path, 1, string.len(path) - 1)
        if (file_exists(string.gsub(path, "?", "test/" .. search_4_file))) then
          test_path = string.gsub(path, "?", "test/?")
          break;
        end
      end
      if (test_path == nil) then
        error("Can't find package files in search path: " .. tostring(package.path))
      end
    end
    
    local main_file = string.gsub(test_path,"?", "main")
    local test = assert(loadfile(main_file))()
    
    -- Load all extensions, i.e. .lua files in Extensions directory
    ext_path = string.gsub(test_path, "[^/]+$", "") .. "Extensions/"
    for extension_file,_ in lfs.dir (ext_path) do
      if (string.match(extension_file, "[.]lua$")) then
        local file = ext_path .. extension_file
        assert(loadfile(file))(test)
      end
    end
    
    return test
    

    如果您遇到同样的问题并发现文档过于稀疏,我希望这会有所帮助。如果您碰巧知道更好的解决方案,请分享。

    【讨论】:

      猜你喜欢
      • 2016-08-26
      • 2014-07-15
      • 2016-05-05
      • 1970-01-01
      • 2016-04-30
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多