2017-09-03 15 views
3

DockerコンテナにメインモジュールといくつかのヘルパーモジュールからなるLuaライブラリを再パッケージしようとしています。道の私は仕事にドッカーコンテナをしたいので、それがあれば、非常に参考になる:メインファイルからの輸入がLua:別の​​作業ディレクトリから相対インポートが失敗する

require 'helpers/SomeHelper' 

問題があるように行われるように、ヘルパー・モジュールは、ライブラリのサブフォルダ内に保持されています私は別の作業フォルダからこのライブラリを呼び出すことができます。つまり、メインプログラムへの私の呼び出しは、私が立っている実際の作業ディレクトリに関係なく、

th /app/main.lua 

のようになります。残念ながら、作業ディレクトリがメインファイルがあるディレクトリと異なる場合、相対インポートは失敗するようです。

これらのインポートを正しく機能させるために、LUA_PATHやその他のメカニズムを構成する方法はありますか?私自身が開発したものではないので、ライブラリ自体のコードを変更することは貧弱な解決策であり、私はそれを新しいバージョンに簡単に更新できるようにしたいと考えています。

答えて

1

あなたが作業ディレクトリを気にしない場合は、あなただけのlfs/LuaFileSytemをロードし、ソースディレクトリに変更しlfs.chdir(src_dir)を使用することができます(潜在的にlfs.currentdir()最初に現在の作業ディレクトリを節約。)

することができますまた、 Luaのsearch pathを拡張して、それらの追加ディレクトリを検索します。検索はpackage.searchpathによって行われます。追加し、すべて正常にサポートライブラリのレイアウトをサポートしています方法で検索するディレクトリ/foo/bar/を追加するには

  • /foo/bar/?.lua;/foo/bar/?/init.luaからpackage.path
  • /foo/bar/?.so(または.dylibまたは他OSENに.dll)へpackage.cpath

いくつかの方法でパスを拡張することができます。

環境変数をLUA_PATH/LUA_CPATHに設定すると効果的です。 (シーケンスのうちの1つのシーケンスは、完全なデフォルトパスに展開されます)。これは、LUA_PATH="..." lua /foo/bar.luaの変数をインラインで設定してexport LUA_PATH="..."またはexport LUA_PATH="..."経由で他のセットアップスクリプトまたは.profileから実行できます。 (この変数を広範囲にエクスポートすると、他のLuaスクリプトもパスが拡張され、互換性のないLuaライブラリが見つかる可能性があります)。package.(c)pathLUA_INITから手動で変更することもできます。独立LUA_INITまたはLUA_PATHを無効にすることはできませんが、あなたは、動的にパスを生成するためのLuaのすべてを使用することができます。)

第三の選択肢(これはあなたの特定のケースでは最高でもよい)package.pathの延長を置くことですメインスクリプトの先頭には、

do 
    local dir = (arg[0]:match "^(.*)/$") 
    if dir then -- else cwd is . which works by default 
     package.path = dir.."/?.lua;"..dir.."/?/init.lua;"..package.path 
     package.cpath = dir.."/?.so;"..package.cpath 
    end 
end 

-- rest of your program goes here 

Luaインタプリタでスクリプトを実行する場合、arg[0]がスクリプトです。このため、プログラムのディレクトリがどこにあるかにかかわらず、そのパスが拡張され、この特定のスクリプト/プログラムの検索パスにのみ影響します。

+0

非常に完全な回答!私はDockerコンテナの中にアプリケーションをパッケージ化しているので、そのコードを変更したくないので、私にとって最適なオプションは、LUA_PATH環境変数を変更することでした。私はLUA_PATH = "/ app /?lua;/app/helpers/?. lua ;;を宣言しなければなりませんでした。必要な操作を行うようにします。 – albarji

0

すべてのモジュールがFSから直接ロードされているわけではありません。 など。パフォーマンスを向上させるために、ファイルをメモリに読み込み/コンパイルすることができます。 は、プリロードテーブルを使用してメモリからモジュールを読み込む方法を提供します。この例では

--- preload code. It can be done by host application. 
local FooUtils = function() 
    return { 
    print = function(...) 
     print("foo", ...) 
    end 
    } 
end 

local Foo = function() 
    local Utils = require "foo.utils" 
    return { 
    foo = function() 
     Utils.print"hello" 
    end 
    } 
end 

package.preload['foo.utils'] = FooUtils 
package.preload['foo'] = Foo 

--- main application 
require "foo".foo() 

Basicの例では、コンパイルされたモジュールのFooUtilsFooだけ例を想定しています。 など。 FooUtils = loadstring('path/to/utils.lua)のようにすることができ、別のルア状態でも を実行してから他の方法で使用することができます。 Fooモジュールでは、ホストアプリケーションがどのように検索するのかについてよく分かりません。foo.utilsです。 オリジナルのファイルパスまたは関連するパスを提供するための標準的な方法はありません。 したがって、相対パスでリレーするモジュールを作成すると、このモジュール が一部の環境で動作していない可能性があります。 だから、require 'utils'の代わりにrequire 'foo.utils'のような完全な名前空間を使用することをお勧めします。

+0

私はこの特定の問題にどのように役立つのか分かりません。特に、これはどのように解決されるのですか?「ライブラリ自体のコードを変更することは、私によって開発されたものではないため、新しいバージョンに簡単に更新できるようにするために、部? ( 'require" foo.bar "' _inside_ライブラリは問題の一部です。) – nobody

+0

luaはそれをかなりうまくサポートしていないので、相対パスは使用しないと言います。 '/ app /?lua'をLUA_PATHに追加することは可能です。しかし、システム全体ではなく、この特定のスクリプトに対してのみ行うべきです。例えば。スタートアップスクリプトを使って – moteus

関連する問題