万年素人からHackerへの道

万年素人がHackerになれるまで殴り書きするぜ。

Unity Advent Calendar 2012 15日目 Title:「UnityScriptのちょいテクニック」

URL: http://atnd.org/events/34621

UnityScriptは嫌いですが、下書きがあったので書きます。
UnityScriptfor文のスコープがJS以上にみたいに甘々なのがむかつくことがあるだろうか?

例えば、以下のように(a)と(b)が同じiを使ってるので変数iが再定義されてると怒られます・・・

// (a)
for (var i=0;i<10;i++) {
    // do something
}

// (b)
for (var i=0;i<10;i++) {
    // do something
}

このへんはJavaScriptみたいにこう↓クロージャ使えば大丈夫です。※これクロージャですよね?違ったら指摘して

for (var i=0;i<10;i++) {
    // do something
}

(function () { // こいつが助けてくれる
for (var i=0;i<10;i++) {
    // do something
}
})();

しかし!!!この場合どうなるか?

#pragma strict

public class USTest extends MonoBehaviour
{
    function Awake() {
        Debug.Log(Hoge("b"));
    }
    
    function Hoge(arg : String) {
        if (arg == "a") {
            var a : int;
            a = 1;
            return a;
        } else if (arg == "b") {
        (function () { // for UnityScripts fuxxin' scope :<
            var a : int;
            a = 2;
            return a; // (1)
        })(); // for UnityScripts fuxxin' scope :<
        }
        return "nothing"; // (2)
    }
}

(1)の「return a;」まで取り囲まれたせいかreturn "nothing";が返って来ます。

↓このようにクロージャ自体を「return」するとOK!

#pragma strict

public class USTest extends MonoBehaviour
{
    function Awake() {
        Debug.Log(Hoge("b"));
    }
    
    function Hoge(arg : String) {
        if (arg == "a") {
            var a : int;
            a = 1;
            return a;
        } else if (arg == "b") {
            return
        (function () { // for UnityScripts fuxxin' scope :<
            var a : int;
            a = 2;
            return a;
        })(); // for UnityScripts fuxxin' scope :<
        }
        return "nothing";
    }
}

→ 2が返るよ。

http://builder.japan.zdnet.com/script/sp_javascript-kickstart-2007/20378258/2/

・inのif文
以下はハマります

#pragma strict

public class USTest1 extends MonoBehaviour
{
    function Awake() {
        // Test1
        if ("C" in ["A", "B"]) {
           Debug.Log("Test1: 1");
        } else {
           Debug.Log("Test1: 2");
        }

        // Test2
        if (!"C" in ["A", "B"] ) {
           Debug.Log("Test2: 1"); // ここを何故か通らない
        } else {
           Debug.Log("Test2: 2");
        }
    }
}

:結果↓

"Test1: 2"
"Test2: 2"

僕はTest2では"Test2: 1"を通ると思いました。
!の位置ですかね?(A, Bにの中に「Cではない」ことが入っている???)

ちなみにこうすれば

        // Test2
        if (!("C" in ["A", "B"]) ) {
           Debug.Log("Test2: 1"); // ここを通る
        } else {
           Debug.Log("Test2: 2");
        }


では、また次の方へ