2016-04-17 9 views
0

In meinem kürzlich in der Entwicklung eines Dataframe-Pakets für Torch geholfen. Da sich die Codebasis schnell verdoppelt hat, muss die Klasse zur besseren Organisation und Nachverfolgung in mehrere Abschnitte aufgeteilt werden (issue #8).Wie man eine Torch-Klasse in mehrere Dateien in einem Lua-Rock zerlegt

würde Eine einfache Test-Klasse eine test.lua Datei im Stammverzeichnis des Testpaketes sein:

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', 
    } 
} 

Antwort

0
:

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

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

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

Nun ist die rockspec hierfür einfach wäre

Damit mehrere Dateien für eine einzelne Klasse verwendet werden können, muss das ursprünglich erstellte Klassenobjekt zurückgegeben und an die Unterabschnitte übergeben werden. Das obige Beispiel kann in der Dateistruktur gesetzt werden:

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

Die luarocks install/make kopiert die Dateien nach ‚require‘ Syntax, wobei jedes . ein Verzeichnis bedeutet und die .lua weggelassen, also müssen wir die rockspec ändern :

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' 
    } 
    } 

oben Der eine Test -Ordner so schaffen, in dem die Pakete mit den Dateien und Unterverzeichnisse zusammen wohnen. Die Klasse der Initialisierung befindet sich nun im init.lua, die die Klasse-Objekt zurückgibt:

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

Die Unterklasse-Dateien zur Abholung müssen jetzt die Klasse-Objekt, das loadfile() geben wird (siehe init.lua Datei unten). Die a.lua sollte nun wie folgt aussehen:

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

und ähnliche zusätzlich für die b.lua:

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

Um alles zusammen zu kleben haben wir die init.lua Datei. Das Folgende ist wahrscheinlich ein wenig zu kompliziert, aber es kümmert sich um:

  • Finden aller verfügbaren Erweiterungen und laden sie (Hinweis: erfordert lua filesystem, die Sie dem rockspec hinzufügen sollten und Sie müssen noch jede Datei hinzufügen es wird nicht in den Ordner Systemerweiterungen sein)
  • Identifiziert die Pfade Ordner
  • Lädt die main.lua
  • Arbeiten in einer reinen Testumgebung ohne das Paket
installiert in den rockspec oder

Der Code für 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 

Ich hoffe, das hilft, wenn man in das gleiche Problem laufen und die Dokumentation etwas zu spärlich finden. Wenn Sie eine bessere Lösung kennen, teilen Sie sie bitte mit.