LSL Style Guide/ja

From Second Life Wiki
Jump to navigation Jump to search

LSL の効果的なプログラミングを行なうには、レイアウトと (コーディングの) 慣習をスクリプトへ適用するよう、制作者が規律正しく実践しなければなりません。

これら、スタイルガイドと呼ばれる集約的要素のガイドラインは、言語コンパイラが必要とするルールほど厳密ではありませんが、それでもなお効率的なメンテナンス性のあるコードを作成するためには必要です。最も効果的なスタイルの様相は、あなたの書くコードに首尾一貫性を持たせることです。

一般的なガイドライン

殆どの人々は、プログラミングの独習を始めた当初は、端的に言うと「醜い」プログラムを書きます。それらは大概、以下のような具合です:

    default {state_entry(){llSay(0,"Hello World.");}}

しかしながら、このコードは一行が一万語で書かれているプログラムの場合、読み解く(あるいは最後まで解釈する)ことが困難です。それ故、プログラマー達は括弧とインデントについて以下の二つの手法を主に用いて、コードを整形します。


手法 1:

    default {
        state_entry() {
            llSay(0, "Hello World.");
        }
    }

手法 2:

    default
    {
        state_entry()
        {
            llSay(0, "Hello World.");
        }
    }

手法1のスタイルでは行数を節約できますが、手法2のスタイルの方が初心者にとってより読みやすくなります。スクリプタは記述スタイルとして実施することにより、さらに読みやすいコードとなるでしょう。首尾一貫したインデントは、さまざまなスタイルをさらに読みやすくします。手法1におけるインデントは、スコープレベルを表現する鍵となります。

命名規則

Second Lifeには、多くの命名規則が存在します。ただ、最も使われるものは次に並んだものでしょう。

グローバル変数(プログラム全体を通して持ちいられる変数)は最初に小文字のgをつけるべきです。

    integer gSelected = 0;
    string  gMyName = "Please set one";

定数として使用する変数は全て大文字を使用します。

    integer CHAT_CHAN = -517265;
    key OWNER_KEY = llGetOwner();


ユーザ定義関数やイベントの中で用いられる引数は、アンダーバー(_)から始めます。

    listen( integer _channel, string _name, key _id, string _message )
    {
        if ( _channel == 1 || _id == llGetOwner() )
        	llOwnerSay("Hello Avatar");
    }

コードの分離

多くの人達は一行で余りにも沢山の関数を呼び出そうとするでしょう。これはコードを読み難くして、極めてデバッグを困難にします。例として、このようなプログラムを挙げてみます。

list lst;
integer numDigits = 10;
default {

   touch_start(integer n) {
       integer i = 0;
       integer index = llListFindList(lst, [llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1))]);
       if (!~llListFindList(lst, [llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1))]))
           lst += llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1));
       llOwnerSay(llList2CSV(lst));
   }

}

先ほどのコードが何を行なっているかあなたに説明できる人は殆どいないでしょうが、以下のコードが何を行なっているかは殆どの人が説明できるでしょう。

list lst;
integer numDigits = 10;

default {
    touch_start(integer n) {
        integer i = 0;
        string name = llKey2Name(llDetectedKey(i));
        list nameAsList = llParseString2List(name, [" "], []);
        string firstName = llList2String(nameAsList, 0);
        string startPart = llToLower(llGetSubString(firstName, 0, numDigits - 1));
        integer index = llListFindList(lst, (list)startPart);
        if (!~index)
            lst += startPart;
        llOwnerSay(llList2CSV(lst));
    }
}

LSL には最適化コンパイラがありません。そのため、より速いコードを実現するには二つのスタイルをバランスよく使う必要があるでしょう。行をまとめてゆく最適化は、コードが動作しバグが無くなってから初めて行なうべきです。不適切な最適化は良くない結果をもたらします。最適化したコードのテストを常に、徹底的に行ないましょう。

list lst;
integer numDigits = 10;

default {
    touch_start(integer n) {
        integer i = 0;
        string startPart = llToLower(llGetSubString(llList2String(llParseString2List(llKey2Name(llDetectedKey(i)), [" "], []), 0), 0, numDigits - 1));
        if (!~llListFindList(lst, (list)startPart))
            lst += startPart;
        llOwnerSay(llList2CSV(lst));
    }
}

スクリプト構成

LSLスクリプトは、関数、ステートメント、イベントハンドラ、ステートの要素によって構成されています。LSLコンパイラはスクリプトに正確な構造化を強制します。

  1. 定義された変数を用いる(LSL_Variablesを参照)
  2. 定義された関数を用いる(ユーザ定義関数を参照)
  3. default State (stateを参照)
  4. 定義されたステートを用いる

エディタ

多くのサードパーティ製エディタとLSL構文ファイルがあります。その他の情報はLSL Alternate Editorsを参照してください。