Difference between revisions of "Jump/ja"

From Second Life Wiki
Jump to navigation Jump to search
m
m
 
(5 intermediate revisions by 2 users not shown)
Line 2: Line 2:
{{LSL Header/ja|
{{LSL Header/ja|
}}{{#vardefine:name|jump
}}{{#vardefine:name|jump
}}{{#vardefine:p_jump_target_desc|ラベル名は階層ツリーで同じスコープ区間の内側です。
}}{{#vardefine:p_jump_target_desc|階層ツリーにおいて、jumpを含む、同じまたは上位のスコープ区間内に存在するラベル名。
}}{{#vardefine:p_label_target_desc|ラベルが同じスコープか子スコープにジャンプできる場合、ジャンプします。
}}{{#vardefine:p_label_target_desc|ラベルは、ラベルと同じか、ラベルが存在するよりも内側のスコープにjumpが存在する場合のみ、ターゲットとなることが出来ます。
言い換えれば、ターゲットは必ずjumpに対して階層ツリーの上位(外側)に存在しなくてはならず、if文の外側から内側に向かってジャンプは出来ません。つまり、異なる関数間、異なる(離れた)スコープ間、異なるステート間でジャンプする事も出来ません。これらのようなコードを書いた場合、単純にjumpに対応するラベルが見つからないと言うコンパイルエラーを起こすでしょう。
 
}}{{#vardefine:header_title|jump {{LSL Param|jump_target|target}};
}}{{#vardefine:header_title|jump {{LSL Param|jump_target|target}};
}}{{#vardefine:header_text|{{{!}}
}}{{#vardefine:header_text|{{{!}}
Line 18: Line 20:
</div>
</div>
}}{{#vardefine:examples|
}}{{#vardefine:examples|
<pre>
<syntaxhighlight lang="lsl2">integer a = 5;
integer a = 5;
jump over;
jump over;
@in;
@in;
Line 27: Line 28:
if(a < 6)
if(a < 6)
     jump in;
     jump in;
//script will say 5 and then 6
//script will say 5 and then 6</syntaxhighlight>
</pre>
<syntaxhighlight lang="lsl2">
integer getLinkWithName(string name)
{
    integer i = llGetLinkNumber() != 0;  // Start at zero (single prim) or 1 (two or more prims)
    integer x = llGetNumberOfPrims() + i; // [0, 1) or [1, llGetNumberOfPrims()]
    for (; i < x; ++i)
    {
        if (llGetLinkName(i) == name)
            jump break; // Found it! Exit loop early with result
    }
    i = -1; // No prim with that name, return -1.
    @break;
    return i;
}
</syntaxhighlight>
ほとんどの場合、特にユーザー定義の関数では、このように上記のスクリプトのバージョンで示されているように、あまり見栄えのしない「ジャンプ」を避けることができます。
<syntaxhighlight lang="lsl2">
integer getLinkWithName(string name)
{
    integer i = llGetLinkNumber() != 0;      // Start at zero (single prim) or 1 (two or more prims)
    integer x = llGetNumberOfPrims() + i; // [0, 1) or [1, llGetNumberOfPrims()]
    for (; i < x; ++i)
    {
        if (llGetLinkName(i) == name)
            return i;                    // Found it, return its index       
    }
    return -1;    // No prim with that name, return -1.
}
</syntaxhighlight>
 
}}{{#vardefine:notes|
}}{{#vardefine:notes|
}}{{#vardefine:caveats|targetは、全てのジャンプは行いません。
他のフロー制御構造が使用できる場合、ジャンプ(一般的にはgotoとして知られています)を使用することは一般的に勧められないと考えられています。
 
* {{Wikipedia|Goto}}
複数に及ぶジャンプのためには、更にtargetを使う必要があるでしょう。
* [http://xkcd.com/292/ XKCD:Goto]
}}{{#vardefine:lso|
<h5>Multiple Jumps Bug</h5>
次の関数、<code>jumpy</code>、は単一のターゲットに対する複数のジャンプサイトのバグを示しています。この関数は無限ループを引き起こすはずであり、Mono VM向けにスクリプトがコンパイルされると実際にはそうなります。しかし、このバグのため、LSO VM向けにコンパイルされた場合、2番目のジャンプは発生せず、関数が返されます。LLはこのバグを修正する意志がないと報告し、それを修正することは互換性の破壊となるため、修正しないと述べました。このバグは新しいMono VMで修正されました。


<syntaxhighlight lang="lsl2">jumpy(){
    jump next;//first jump
    @next;
    jump next;//second jump - BUG never gets executed
    return;
}</syntaxhighlight>


''技術的な限界、見落とし、バグの場合、常に無いものとして扱われます。''
}}{{#vardefine:caveats|
*ひとつのtargetと複数のjumpを使った場合、必ずしも全ての場合でジャンプが実行されるわけではありません。 複数のジャンプのためには、更にtargetが必要となる場合があるでしょう。 これは、長く知られたLSLのバグです。
*'''[[LSO]] のみ注意事項:''' 同じスコープ内で同じターゲットラベルに対して複数のジャンプサイトが宣言されている場合、最初のものだけが期待通りに機能し、他のすべては無音で失敗します。
*ラベルはイベントと関数のレベルでスコープが設定されており、つまり、同じイベントや関数内で同じラベルを宣言することはできないため、異なるif文、ループなどでラベルを囲んでいても重複したラベルを宣言することはできません。 -- {{JIRA|SVC-6712}}
**これを試みると、スクリプトはコンパイル時に無音の失敗となります。
*returnの後にコードが存在し、それがフロー制御構造で囲まれていない場合、コンパイラはコードがアクセス可能であっても、コードが無効であるというエラーを返します。 -- {{Jira|SVC-1929}}
}}{{#vardefine:helpers|
}}{{#vardefine:helpers|
}}{{#vardefine:also_header|<h3>キーワード</h3>
}}{{#vardefine:also_header|<h3>キーワード</h3>
Line 48: Line 92:
}}{{#vardefine:also_tests|
}}{{#vardefine:also_tests|
}}{{#vardefine:location|
}}{{#vardefine:location|
}}{{LSL Generic/ja}}{{LSLC|Flow Control/ja}}
}}{{LSL Generic/ja}}{{LSLC/ja|Flow Control}}

Latest revision as of 08:12, 26 September 2023

The correct title of this article is jump/ja. The initial letter is shown capitalized due to technical restrictions.

jump target;

jump target;
• label target 階層ツリーにおいて、jumpを含む、同じまたは上位のスコープ区間内に存在するラベル名。

@target;

• label target ラベルは、ラベルと同じか、ラベルが存在するよりも内側のスコープにjumpが存在する場合のみ、ターゲットとなることが出来ます。

言い換えれば、ターゲットは必ずjumpに対して階層ツリーの上位(外側)に存在しなくてはならず、if文の外側から内側に向かってジャンプは出来ません。つまり、異なる関数間、異なる(離れた)スコープ間、異なるステート間でジャンプする事も出来ません。これらのようなコードを書いた場合、単純にjumpに対応するラベルが見つからないと言うコンパイルエラーを起こすでしょう。

注意点

  • ひとつのtargetと複数のjumpを使った場合、必ずしも全ての場合でジャンプが実行されるわけではありません。 複数のジャンプのためには、更にtargetが必要となる場合があるでしょう。 これは、長く知られたLSLのバグです。
  • LSO のみ注意事項: 同じスコープ内で同じターゲットラベルに対して複数のジャンプサイトが宣言されている場合、最初のものだけが期待通りに機能し、他のすべては無音で失敗します。
  • ラベルはイベントと関数のレベルでスコープが設定されており、つまり、同じイベントや関数内で同じラベルを宣言することはできないため、異なるif文、ループなどでラベルを囲んでいても重複したラベルを宣言することはできません。 -- SVC-6712
    • これを試みると、スクリプトはコンパイル時に無音の失敗となります。
  • returnの後にコードが存在し、それがフロー制御構造で囲まれていない場合、コンパイラはコードがアクセス可能であっても、コードが無効であるというエラーを返します。 -- SVC-1929

サンプル

integer a = 5;
jump over;
@in;
a = 6;
@over;
llOwnerSay((string)a);
if(a < 6)
    jump in;
//script will say 5 and then 6
integer getLinkWithName(string name)
{
    integer i = llGetLinkNumber() != 0;   // Start at zero (single prim) or 1 (two or more prims)
    integer x = llGetNumberOfPrims() + i; // [0, 1) or [1, llGetNumberOfPrims()]
    for (; i < x; ++i) 
    {
        if (llGetLinkName(i) == name) 
            jump break; // Found it! Exit loop early with result
    }
    i = -1; // No prim with that name, return -1.
    @break;
    return i;
}

ほとんどの場合、特にユーザー定義の関数では、このように上記のスクリプトのバージョンで示されているように、あまり見栄えのしない「ジャンプ」を避けることができます。

integer getLinkWithName(string name)
{
    integer i = llGetLinkNumber() != 0;      // Start at zero (single prim) or 1 (two or more prims)
    integer x = llGetNumberOfPrims() + i; // [0, 1) or [1, llGetNumberOfPrims()]
    for (; i < x; ++i) 
    {
        if (llGetLinkName(i) == name) 
            return i;                    // Found it, return its index        
    }
    return -1;     // No prim with that name, return -1.
}

注意点

他のフロー制御構造が使用できる場合、ジャンプ(一般的にはgotoとして知られています)を使用することは一般的に勧められないと考えられています。

参考情報

キーワード

•  return
•  state

特記事項

LSO VM Notes

Multiple Jumps Bug

次の関数、jumpy、は単一のターゲットに対する複数のジャンプサイトのバグを示しています。この関数は無限ループを引き起こすはずであり、Mono VM向けにスクリプトがコンパイルされると実際にはそうなります。しかし、このバグのため、LSO VM向けにコンパイルされた場合、2番目のジャンプは発生せず、関数が返されます。LLはこのバグを修正する意志がないと報告し、それを修正することは互換性の破壊となるため、修正しないと述べました。このバグは新しいMono VMで修正されました。

jumpy(){
    jump next;//first jump
    @next;
    jump next;//second jump - BUG never gets executed
    return;
}