白猫のメモ帳

JavaとかJavaScriptとかHTMLとか機械学習とか。

プロパティとかインデクサはインクリメントできる

こんにちは。

気温の変化についていけない私です。
今日はC#ネタ。

C#にはプロパティという便利な機能があります。
Javaばっかり書いていた私としては単なるアクセサの便利な書き方くらいに思っていたのですが、
ふと違いに気づいたのでメモ。

たとえばこんなint型のプロパティを持つクラスを作って、

class Test
{
    internal int Cnt { get; set; }
}

こんな風にインクリメントするとちゃんと演算してくれます。

var test = new Test();
Console.WriteLine(test.Cnt);
test.Cnt++;
Console.WriteLine(test.Cnt);

0
1

おお賢い。
ということはきっとインデクサもこんな風にすれば、

class Test
{
    private int[] ary = new int[1];
    internal int this[int i]
    {
        get => ary[i];
        set => ary[i] = value;
    }
}

インクリメントできる!

var test = new Test();
Console.WriteLine(test[0]);
test[0]++;
Console.WriteLine(test[0]);

0
1

単なるgetterだと考えるとこんなことはできません。
(intは参照型じゃないので)

これはインクリメント演算子がちゃんとgetterで取って、setterで入れているからなんでしょう。
ということはですよ、こんないたずらをすれば・・・

private int cnt;
internal int Cnt
{
    get => cnt;
    set => cnt = value + 1;
}

インクリメントしただけなのに、

var test = new Test();
Console.WriteLine(test.Cnt);
test.Cnt++;
Console.WriteLine(test.Cnt);

0
2

2増えた!

なるほど。楽しい。
よいこは真似しないようにしましょう。

closestメソッドは自身を含むよ

こんばんは。

ずいぶん久しぶりになってしまいました。
台風が近づく三連休初日、いかがお過ごしでしょうか。

さて、もうタイトルがすべてっていえばそれまでなのですが、
久しぶりにまじめにJavaScript(jQuery)を書いたら罠にはまったのでメモ。

.closest()ってどんなメソッド

.closest() | jQuery API Documentation

リンク先に

For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.

とあるように、DOMツリー内の祖先をトラバース、
つまり自身の要素をもとに外側に辿って行き、一番最初に見つかった要素を返すメソッドです。

<ul>
    <li id="item1">その1</li>
    <li id="item2">その2</li>
</ul>

というDOMに対して、

$("#item1").closest("ul");

と書くと直上のul要素を取得できます。
これは「.parent()」メソッドを使っても変わりません。

<ul>
    <li class="item"><a href="#">その1</a></li>
    <li class="item"><a href="#">その1</a>その2</li>
</ul>

というDOMに対して、

$("#item1 a").closest("ul");

としても、セレクタに一致するまで遡ってくれるのでul要素を取得できます。
parentを使っている場合よりも柔軟な構造変更が可能なわけです。

で、罠

DOMをもうちょっと複雑にしてみます。いわゆる入れ子構造。

<ul id="list1">
    <li id="item1">
        <ul id="item1-list1">
            <li id="item1-1">その1の1</li>
            <li id="item1-2">その1の1</li>
        </ul>
    </li>
    <li id="item2">その2</li>
</ul>

ディレクトリとか表現するときにはよくあるパターンですね。

$("#item1-1").closest("ul");

とすると当然直上のul、つまり#item1-list1を取得することができます。
されにその外側のulまで遡ろうとして、こう書くと、

$("#item1-1").closest("ul").closest("ul");

#list1が取れません
取れている要素を確認してみると#item1-list1になっています。

要するに先祖と言っている中には自分自身を含んでいるってことですね。

$("#item1-1").parents("ul").eq(1);

とかがいいのかな。もっといい方法あるのかな。

そんな罠に掛ったよっていうお話でしたとさ。

無限subst地獄

こんばんは。

突然の豪雨に窓の周りがびしょ濡れになりました。
ちゃんと窓を閉めて出かけましょう。

さて、Windowsにはsubstという便利なコマンドがあります。
このコマンドは任意のディレクトリをドライブに割り当てることができます。

subst F: C:\Temp

とすれば、「C:\Temp」ディレクトリがFドライブに割り当てられるわけです。

便利なのでバッチにします。
名前はわかりやすく「subst.bat」でいいでしょう。

で、実行すると…。

f:id:Shiro-Neko:20170729184810p:plain

うぁぁぁぁぁぁ。

恐ろしい勢いでコンソールが流れていきます。

なんじゃこりゃ一体って感じですが、実はこれ「subst」が自身のバッチファイルを指してしまっていて、
自分自身をひたすらコールし続けているみたいです。

バッチファイルを作る際には名称をコマンド名と一緒にしないように気をつけましょう。
それでは。