2009-06-02 7 views
13

現在、私はLuaを埋め込み、それを賢明なインテリジェントな設定ファイルとして使用しています。しかし、私はLuaの使用について人々が賞賛して以来、何かが欠けていると思います。LuaがC/C++よりもはるかに優れている使用例

あなたはこの例を示すことによって、代わりにCのシェルスクリプトを使用する場合がありますなぜたとえば、私は簡単に説明することができます(確かに、ブースト正規表現は行き過ぎです):

#include <dirent.h> 
#include <stdio.h> 
#include <boost/regex.hpp> 

int main(int argc, char * argv[]) { 
    DIR   *d; 
    struct dirent *dir; 
    boost::regex re(".*\\.cpp$"); 
    if (argc==2) d = opendir(argv[1]); else d = opendir("."); 
if (d) { 
    while ((dir = readdir(d)) != NULL) { 
      if (boost::regex_match(dir->d_name, re)) printf("%s\n", dir->d_name); 
    } 

    closedir(d); 
} 

return(0); 

とそれを比較します。

for foo in *.cpp; do echo $foo; done; 

Luaで私が「クリック」できる例がありますか?

編集:多分私の問題は、私がC言語を書いたほうが簡単だから、流暢に使えるようになっていて、まだLuaをよく知らないということでしょう。

EDIT2:

一例は、C++とLuaの中におもちゃ階乗のプログラムです:

#include <iostream> 

int fact (int n){ 
    if (n==0) return 1; else 
    return (n*fact(n-1)); 
} 

int main(){ 
    int input; 
    using namespace std; 
    cout << "Enter a number: " ; 
    cin >> input; 
    cout << "factorial: " << fact(input) << endl; 
    return 0; 
} 

のLua:ここ

function fact (n) 
    if n==0 then 
     return 1 
    else 
     return n * (fact(n-1)) 
    end 
end 

print ("enter a number") 
a = io.read("*number") 
print ("Factorial: ",fact(a)) 

、プログラムは同じように見えますが、いくつかの嫌なものが明確にありますあなたが取り除くことができるinclude、namespace宣言およびmain()宣言の中にあります。また、変数の宣言と厳密な型定義も削除します。

これは、これが大規模なプログラムに加わる利点であると言っている人はいますか?これはbashの例と同じようには目立たない。

+0

重複したhttp://stackoverflow.com/questions/591523/when-is-it-good-to-use-embedded-script-language-like-lua? –

+0

他のプログラミング言語を学ぶことで、より良いプログラマができます。あなたはCでも違った考え方を学びます。 – 0x6adb015

+0

近い方向の重複は、異なる方向から同じ種類の質問に近づいています。それらをクロスリンクするのは良いですが、私はこれを「正確な」複製と見なしません。 – RBerteig

答えて

10

Luaなどのスクリプト言語を使用すると、他にも多くの利点があります。

Luaの対C++の利点のカップル:

  • それはあなたの例のように、ハイレベルな性質のため、開発時間の面で、多くの場合、短いです。
  • 動作を変更するために再コンパイルする必要はありません。
  • 非開発マシンで動作を変更することができます。
  • プロトタイプ作成は非常に高速で簡単です。実行時にロジックを調整するだけで済みます。
+3

...機能は変更でき、非開発者によって拡張/改良することができます – none

+1

@none:良い点ですが、私はまだLua自身のプログラミング言語を考慮していますので、IMO、あなたはまだ "開発者"が必要です経験の少ない方)。 –

3

C/C++でLuaテーブルを実装しようとすると、そこにLuaの強みが見えます。 Luaので

:Cで

a["index"] = "value" 

、リンクリストについて読むことから始め...

C++ STLは役立つかもしれないが、多くの、より詳細なLuaのよりになるだろう。

でも、Luaは素晴らしい接着剤です。 Cとインターフェースするのはとても簡単です(0123)。

+0

ありがとうございます。 QtのQListを使ったことがありますか?似たものを提供しているのかどうか疑問に思うだけです。 – bugmenot77

+0

いいえ、私は同じようなものを提供するいくつかのlibがあると確信していますが、Luaと同じくらい簡単ですか? – 0x6adb015

+3

C++のstd :: map についてはどうですか? – bdonlan

3

私はそれを「クリック」するかどうか分かりませんが、試してみます。

Luaを組み込む利点の1つは、configfileとして使うことができるだけでなく、Luaスクリプト言語を使ってluaに実際にC/C++インターフェイスを提供し、そのスクリプトを使用することです。

アプリケーションの動作/ロジックを変更したい場合は、アプリケーション全体を再コンパイルせずに、Luaスクリプトのコードを変更するだけで済みます。

顕著な用途は、ゲーム開発のためにプレイからゲームへの速い往復時間が不可欠な、AIその他の状態マシンのようなゲームロジックです。

もちろん、メインロジックは、効果的に使用するために、C/C++コード内ではなく、Luaスクリプト内に存在する必要があります。

+0

ありがとうございます。私はおそらく少し誇張し、ゲームロジックでAIを実装するためにLuaを使用します。これを行うには、C、Lua、またはいくつかのミックスで実装する必要があるかどうかという問題が出てきました。 – bugmenot77

1

Luaが適している場所の例として、C++ではスクリプトの配布を見ています。 Mush Clientは、スクリプト言語としてLuaを提供しています。上のリンクで示されているように、あなたはLuaを使ってプログラムを拡張することができます。 C++とは異なり、Luaはコンパイルする必要がなく制限することができます。たとえば、Luaをサンドボックス化してファイルシステムにアクセスすることはできません。つまり、他の人からスクリプトを入手した場合、ディスクに書き込めないため、データを破壊することはできません。

+0

ありがとうございます。私はLuaが埋め込まれているか、プラグイン、スクリプトなどの拡張、拡張に使用されているケースを完全に見ることができます。しかし、速度が重要な場合は、CからLuaへの切り替えとCモジュールの記述だけも聞きます。私はおそらく私はLuaで十分に流暢ではないと思うし、もし私がいたなら、CよりLuaでより速く/簡単に書くことができたでしょう。 – bugmenot77

+0

C++/Cはサンドボックス化されていても制限されていてもかまいません。 NaClを見てください。 – Alice

2

C言語でのプログラミングは、非常に面倒で冗長な作業です。これは、より抽象的な高水準言語と比較した場合、確かに当てはまります。

この意味では、C言語で直接すべてを行うよりもはるかに迅速に作業を開始できます。これは、Cで明示的に手動で設定、実行、およびクリーンアップする必要がある多くのことが、 Lua(例えば、メモリ管理を想像する)のようなスクリプト言語によって自動的に処理されます。

同様に、多くの抽象的なデータ構造とアルゴリズムは、そのような高水準言語によって直接提供されることが多いため、必要なものが標準のコンテナであれば、ホイールを再作成して再実装する必要はありませんリンクリスト、ツリー、地図など)

LuaやPythonなどのかなり抽象的なスクリプト言語を使用している場合、特に対応する言語に優れたコア機能ライブラリが含まれている場合は、ROIをかなり高くすることができます。

したがって、ほとんどのプロジェクトで同一である可能性が高いすべての機械的冗長性ではなく、自分の努力に集中する必要があるため、アイデアやプロジェクトのプロトタイプ作成にはスクリプティングが理想的です。

基本的なプロトタイプを完成させたら、ランタイムパフォーマンスを向上させるために、Cスペースで不可欠なキー機能を再実装することができます。

+0

ありがとうございます。 2回目の編集で示されたことを意味しますか? – bugmenot77

1

プログラミング言語としてのLuaの主な利点(離れ埋め込みからは)

  • 強力な、効率的なハッシュテーブルであるメインデータ構造として複雑さの優れたバランスを有する
  • 文字列処理ライブラリおよび表現力
  • ファーストクラス関数と汎用forループ
  • 自動メモリ管理!

これらのすべてを示す簡単な例はありません。私は~/binディレクトリに191個のLuaスクリプトを持っています。ここpstotextの出力を受け取り、ハイフンで終わる行を結合し一つだ:

local function printf(...) return io.stdout:write(string.format(...)) end 
local function eprintf(...) return io.stderr:write(string.format(...)) end 

local strfind, strlen = string.find, string.len 

function joined_lines(f) 
    return coroutine.wrap(function() 
          local s = '' 
          for l in f:lines() do 
          s = s .. l 
          local n = strlen(s) 
          if strfind(s, '[%-\173]$', n-1) then 
           s = string.sub(s, 1, n-1) 
          else 
           coroutine.yield(s) 
           s = '' 
          end 
          end 
         end) 
end 

-- printf('hyphen is %q; index is %d\n', '­', string.byte('­')) 

for _, f in ipairs(arg) do 
    for l in joined_lines(io.popen('pstotext ' .. f, 'r')) do 
    printf('%s\n', l) 
    end 
end 

この例は、有利には、いくつかの特徴を示していますが、テーブルと興味深い何もしません。

ここでは、テーブルからコンテキストを取り出してコンテキスト内のキーワードをフォーマットする、キーワードインコンテキストインデックス作成プログラムの短いスニペットを示します。この例は、ネストされた機能のより広範な利用を行い、いくつかのより多くのテーブルと文字列のものを示しています

local function showpos(word, pos, lw, start) 
    -- word is the key word in which the search string occurs 
    -- pos is its position in the document 
    -- lw is the width of the context around the word 
    -- start is the position of the search string within the word 
    local shift = (start or 1) - 1 -- number of cols to shift word to align keys 
    lw = lw - shift -- 'left width' 
    local rw = cols - 20 - 3 - lw - string.len(words[pos]) -- right width 
    local data = assert(map:lookup(pos)[1], "no map info for position") 
    -- data == source of this word 
    local function range(lo, hi) 
    -- return words in the range lo..hi, but only in the current section 
    if lo < data.lo then lo = data.lo end 
    if hi > data.hi then hi = data.hi end 
    local t = { } 
    for i = lo, hi-1 do table.insert(t, words[i]) end 
    return table.concat(t, ' ') 
    end 
    -- grab words on left and right, 
    -- then format and print as many as we have room for 
    local left = range(pos-width, pos) 
    local right = range(pos+1, pos+1+width) 
    local fmt = string.format('[%%-18.18s] %%%d.%ds %%s %%-%d.%ds\n', 
          lw, lw, rw, rw) 
    printf(fmt, data.title, string.sub(left, -lw), word, right) 
end 
+1

std :: unordered_map、std :: string、ループとラムダ用のC++ 11、RAIIとstd :: shared_ptrはすべて、luaの選択肢と同じように高速で使いやすいものです。 – Alice

4

スクリプト言語は、そうでない場合は、フレームワークグルーとコードの繰り返しの多くを必要とする複雑なGUIを構築するために必要な労力を削減します。 LUAバインディングには、wxWidgetsIUP toolkitなど、いくつかのGUIツールキットが用意されています。

これらの両方のバインディングでは、ファーストクラスのファンクション値と完全なクロージャによって、イベントコールバックを簡単にコーディングして使いやすくします。

コアでLuaを使用する大規模なアプリケーション(Adobe Photoshop Lightroomなど)には、Luaインタプリタをホストする外部C/C++プログラムがあり、C関数をそのインタープリタに登録することによってそのコア機能にアクセスできます。これは通常、Cの関数では計算集約的なコア関数を実装しますが、全体的なフロー、操作、およびGUIレイアウトさえもLuaスクリプトに任せます。

実行時にロードされたIUPと1つまたは複数のIUPを組み合わせて使用​​すると、スタンドアロンのLuaインタープリタ(lua.exeまたはwlua.exe)で十分であることが、自分のプロジェクトで判明しました。そのレベルの性能を必要とする機能を実装するC言語でコード化された2つのカスタムDLLベースのLuaモジュール、または他のC呼び出し可能ライブラリを介して実装された機能私のプロジェクトのための

重要なポイントが含まれています:

  • 真の末尾再帰は有限状態機械の容易な発現を可能にします。
  • ガベージコレクションされたメモリ管理。
  • 匿名関数、クロージャ、ファーストクラスの関数値。
  • ハッシュテーブル。
  • 十分に豊富な文字列ライブラリ。
  • UserdataはガベージコレクタをC側の割り当てに拡張します。
  • メタテーブルでは、オブジェクト指向と機能的なテクニックが豊富に用意されています。
  • 小さくても十分に強力なC API。
  • 良いdocumentation、オープンソースをバックアップとして使用しています。
  • mailing listwikiを使用して、ユーザーとユーザーとの間の良好な関係をサポートします。
  • PEGパーサーのような強力なモジュールと、著者とcommunityから入手できます。

私が好きな例として挙げたのは、約1000行のLuaと1000行のCを必要とし、lua.exeの下で実行され、IUPを使ってWindows全体を表示する組み込みシステム向けに構築されたテストジグですGUI。最初のバージョンは約1日で実行されていました。MFCを使用したC++では、少なくとも1週間の作業と数千行のコードが必要でした。

+0

テールコールは常に反復処理に変えることができます。RAIIは、ごみ、C++ 11ラムダ、 'std :: unordered_map'、' std :: string'、 'stlport :: rope'を持たないことを意味します。 boost :: mixins'と 'boost :: spirit'を使っています。あなたが言ったことは、LuaがC++よりも優れていることを示しているわけではありません。私はあなたがLuaで書いたよりも短時間でQTを使ってプログラムを書いたことができることを保証します。 – Alice

1

私はゲームを書くためにLuaを使用するLove2Dというゲームエンジンを使用します。すべてのシステムコールと大掛かりな作業は、Luaスクリプトを読み込むCプログラムで行われます。

CまたはC++でゲームを書くと、自分のアイデアを実装するのではなく、システムの微妙なところで作業しようとします。

Luaでは、「きれいな」ダーティースタイルのコーディングが可能です。

は、ここで純粋なのLUAで書かれたゲームオブジェクトの例です:

local GameObj = {}    -- {} is an empty table 
GameObj.position = {x=0,y=0} 
GameObj.components = {} 

function GameObject:update() 
    for i,v in ipairs(self.components) do -- For each component... 
     v:update(self)      -- call the update method 
    end 
end 

インスタンス化するには:

myObj = setmetatable({},{__index=GameObj}) 
-- tables can have a meta table which define certain behaviours 
-- __index defines a table that is referred to when the table 
-- itself doesn't have the requested index 

はのは、どのようにキーボード制御に関するコンポーネントを定義してみましょうか?私たちはこのmyobjを呼び出すときに私たちは私たち(その供給されるだろうC-側)の入力を行うオブジェクトを持っていると仮定すると

KeyBoardControl = {} 
function KeyBoardControl:update(caller) 
    -- assuming "Input", an object that has a isKeyDown function that returns 
    -- a boolean 
    if Input.isKeyDown("left") then 
     caller.position.x = caller.position.x-1 
    end 
    if Input.isKeyDown("right") then 
     caller.position.x = caller.position.x+1 
    end 
    if Input.isKeyDown("up") then 
     caller.position.y = caller.position.y-1 
    end 
    if Input.isKeyDown("down") then 
     caller.position.y = caller.position.y+1 
    end 
end 
--Instantiate a new KeyboardControl and add it to our components 
table.insert(myObj.components,setmetatable({},{__index=KeyboardControl}) 

は今:アップデートが()、それは入力をチェックし、移動することが

のは、私たちを言ってみましょう今、私たちは一緒にプレイすることができますKeyObjのテーブルを持っている

KeyObj = setmetatable({}, {__index = GameObj}) 
table.insert(KeyObj.components,setmetatable({}, {__index = KeyboardControl})  

myKeyObjs = {} 

for i=1,10 do 
    myKeyObjs[i] = setmetatable({}, {__index = KeyObj}) 
end 

:「KeyboardControlとGameObjのこの種の多くを使用できるでしょう、私たちは、継承されたオブジェクトを好きなプロトタイプKeyObjと使用をインスタンス化することができます。 ここで、Luaが、私たちが解決しようとしている問題に応じてプログラムを構築することを可能にする、強力で拡張が容易な柔軟なオブジェクトシステムを提供する方法を見てみましょう。言語。

また、ルアにはファーストクラスの関数としての機能のような素晴らしい機能がいくつかあり、ラムダプログラミング、匿名関数などがあります。

1

LUAはclosuresであり、ロックを閉じます。 exampleの場合:

function newCounter() 
    local i = 0 
    return function() -- anonymous function 
      i = i + 1 
      return i 
     end 
end 

c1 = newCounter() 
print(c1()) --> 1 
print(c1()) --> 2 

関数を作成して渡すことができます。別のクラスを作成してインスタンス化するよりも便利な場合もあります。

+4

C++も同様です。 C++ 11およびC++ 14ラムダを参照してください。 – Alice

関連する問題