ごらくらいふ

プログラミングしたりゲームしたり

メソッドの責任について考えたログ

エラー処理という名のガードレールが無いプログラミングを続けてきた。 慣れないことを考えたので思案のログを残す。

条件設定

あるコレクションのメソッドにて、引数の識別子に一致する要素を探し、仕事をさせる。 この時、引数が存在しないとき(undefined, null)デフォルトの値を使用する。

雰囲気つかみ

class Worker {
  digOilfield(): boolean{};
}

class WorkerCollection {
  workerList: Worker[];

  digOilfieldWithId(id: number): boolean{
  }

  takeDefaultId(): number {
  }
}

let workerCollection = new WorkerCollection();

digOilfieldWithId の引数に対して、どこまで不安になればいいのか考えていた。

思案1: digOilfieldWithId の中でデフォルトIDを取っちゃえ

class WorkerCollection {
  workerList: Worker[];

  digOilfieldWithId(id: number): boolean{
    if(!id){
      id = this.takeDefaultId();
    }
    this.workerList[id].digOilfield();
  }

  takeDefaultId(): number {
  }
}

let workerCollection = new WorkerCollection();

/* workerをかき集めたりする */

workerCollection.digOilfieldWithId(id);

一旦書いて、undefinedやnulllが問題じゃなく、Workerが逃亡しているかどうかのほうが重要だなと思った。

改善

class WorkerCollection {
  workerList: Worker[];

  digOilfieldWithId(id: number): boolean{
    if(!this.workerList[id]){
      id = this.takeDefaultId();
    }
    this.workerList[id].digOilfield();
  }

  takeDefaultId(): number {
    // 必ず有効なIDを返す
  }
}

let workerCollection = new WorkerCollection();

/* workerをかき集めたりする */

workerCollection.digOilfieldWithId(id);

「指定のIDに仕事をさせる」という名称なのに、居ないからという理由で他のIDに仕事をさせるのは、名前に嘘をついており”無責任”なのではと思う。

いると思ったID:10に仕事をさせたつもりが、じつはID:1が仕事をしてしまうのは使う側に対して無責任。*1

思案2: 使う側にちょっと手をかけさせる

class WorkerCollection {
  workerList: Worker[];

  digOilfieldWithId(id: number): boolean{
    this.workerList[id].digOilfield();
  }

  takeDefaultId(): number {
    // 必ず有効なIDを返す
  }

  existsWorkerWithId(id:number): boolean{}
}

let workerCollection = new WorkerCollection();

/* workerをかき集めたりする */

if( !workerCollection.existsWorkerWithId(id) ){
  id = workerCollection.takeDefaultId();
}
workerCollection.digOilfieldWithId(id);

確かに使う側が気を使って引数を厳選すれば回避できるかもしれないが、それは責務が違う。 それにdigOilfieldWithIdがまた隙だらけになってしまった。

思案3: digOilfieldWithIdもっと怒れ

class WorkerCollection {
  workerList: Worker[];

  digOilfieldWithId(id: number): boolean{
    if( !this.workerList[id] ) {
        throw Error("そんな奴ァいねぇ!!");
    }
    this.workerList[id].digOilfield();
  }

  takeDefaultId(): number {
    // 必ず有効なIDを返す
  }

  existsWorkerWithId(id:number): boolean{}
}

let workerCollection = new WorkerCollection();

/* workerをかき集めたりする */

if( !workerCollection.existsWorkerWithId(id) ){
  id = workerCollection.takeDefaultId();
}
workerCollection.digOilfieldWithId(id);

メソッドの名前と異なることをしちゃあいけない。でも有効な値だけをもらえるかもわからない。 いざ無効な値が来たときどうする。

もう怒るしかない。怒ることを使う側は知るべきだ。

思案4: 使う側は手間をかけたくない

class WorkerCollection {
  workerList: Worker[];

  digOilfieldWithIdOrDefaultId(id: number): number{
    if( !workerCollection.existsWorkerWithId(id) ){
      id = workerCollection.takeDefaultId();
    }
    return this.digOilfieldWithId(id);
  }

  digOilfieldWithId(id: number): boolean{
    if( !this.workerList[id] ) {
        throw Error("そんな奴ァいねぇ!!");
    }
    this.workerList[id].digOilfield();
  }

  takeDefaultId(): number {
    // 必ず有効なIDを返す
  }

  existsWorkerWithId(id:number): boolean{}
}

let workerCollection = new WorkerCollection();

/* workerをかき集めたりする */

workerCollection.digOilfieldWithIdOrDefaultId(id);

引数IDが無効ならばデフォルトIDを使うことを明言した。*2

この処理を使うということはデフォルトIDが使用されるかもしれないことを、使う側に認識させることができた。

とりあえずここで止め。

*1:そして副作用がID:1に起こってトラブルにつながるかもしれない

*2:流石に名前がおかしい気がする

typescript環境作りに2時間かかってたのでスクリプトを書いた

でもやめられない。

好みの構成はある。既存のコピーじゃ環境が古いままになるのはイヤ。

yeomanやってみようかと思ったけどまた学習コスト積むのもまたドツボに嵌りそうなのでシェルスクリプトでやる。

やった。

lessとかぜんっぜんないけど。

なお計測したところこのスクリプト作成に4時間かかったらしい。3回作ればもとが取れるわけだ。

generate project for typescript

参考リンク

抱き枕カバーを洗った

時が来た。 ここ3年ほど荒れていた布団事情が改善され、抱きまくら封印を解く時が。

ファーファの中性洗剤でカバーを手もみ洗い。汚れる桶。 封印前からの汚れが出るわ出るわで謝罪した。

封印期間も長過ぎたので週一で洗って改善したほうがよさそうだ。

乾くの待ってるぞ。 天使ちゃんマジ天使。

参考リンク

Everythingをアプリケーションランチャとして使う

Mac使ってると、spotlight検索でパパっとアプリケーションを起動できる点が本当に便利に感じる。

Windowsでも似たようなことできないかと思ってEverythingを取り出した。

Everything Search Engine

基本方針

  1. Desktopにショートカット集積ディレクトリを作る
  2. ディレクトリをEverythingで参照する

MacのApplicationディレクトリと違ってProgram Files中にある.exeの深さがまちまちだったり、.exeで検索すると求めていないものがマッチしたりする。*1

なので、使いたいアプリケーションへのショートカットリンクを集め、そこを検索する方針にした。

環境

何をした

ブックマーク追加

メニューからブックマークを追加した。

  • 名称をLaunchにした
  • 検索にpath:C:\Users\username\Desktop\shortcuts file:と指定した
  • キー割当はCtrl+Lとした

ワンタッチでEverything起動+Launchブックマークを使う

Launchのマクロ登録
  • Launchブックマークを編集する
    • マクロにlaunchと設定

f:id:yajamon:20161026110653p:plain

オプションを調整する
  • 全般->インターフェース
    • バックグラウンド実行を有効化
  • 全般->新規ウィンドウ時(Home)
    • 検索文字欄にlaunch:を指定
  • 全般->結果
    • ファイル起動時にeverythingを閉じる
  • 全般->キー割当
    • 新規検索ウィンドウにWin+Fを指定

f:id:yajamon:20161026110915p:plain

いい感じだ

Winキー -> 検索でいいんじゃないの

おもった。

まぁchromeでWebページをアプリっぽく開くショートカットはスタートメニューに出てこないから……

*1:chrome」でHitする大量のinstallerとか

WinMerge日本語版をSourceTreeのマージツールにセットした

結論

Diffコマンド

WinMergeまでのPath

引数

-e -u -wl -wm -fr -dl 'Base file [read only]' -dm ' Theirs fise [read only]' -dr 'Mine file' -ar $BASE $REMOTE $LOCAL -o $MERGED

想定

3ペイン方式。

ペイン 役割
左ペイン Base file
中央ペイン Theirs file
右ペイン Mine file

各オプション

-e

EscキーでWinMergeを閉じる

-u

左ペイン、中央ペイン、右ペインで開いたファイルが、 最近使用した項目リストに追加されるのを防ぐ

-wl

左ペインを読み取り専用で起動する

-wm

中央ペインを読み取り専用で起動する

-fr

起動時、右ペインにフォーカスする

-dl 'text'

左ペインのタイトルバーを設定する

-dm 'text'

中央ペインのタイトルバーを設定する

-dr 'text'

右ペインのタイトルバーを設定する

-ar

右ペインで自動マージを試みる

-o

マージ結果を出力先

$MERGED をセットしておけばいい

参考リンク

マニュアルとにらめっこした後に調べてみると先人の知恵がすぐ出てくる現象

好意をむやみに期待してはいけない

今朝はシンデレラガールズ4thライブの会場限定CDを求めてSSAに突撃した。 目的をまぁまぁ達成し、城とかぴにゃとかドールとか展示を堪能したんだけどやばい。この時点での多幸感がやばい。

さてLVに備えるだけだと息巻けば既にiPhone虫の息。

心許ない電池残量でちょいと調べると、LV現地周辺にはどうも電源カフェなるものがあるらしい。 これが恵みか、などとのたまいコンセント→USBを買って店舗に入ったところ、どうもコンセントが見当たらない。 正確にはコンセントユニットに換装出来そうなプレートしか無かった。

おそらくやめたのだろう。営業戦略あってこその好意は割に合わなければ続ける意味はない。

コーヒーをひとつ頼み、座席回転率に貢献した後は、乾電池式の充電器を買いに走ったのだった。

「コンセントを提供しているかも」とか「充電済みで売ってるモバイルバッテリーは満充電かも」とか、店側の好意をむやみに期待してはいけない。 いや、勝手に期待してもいいけど勝手に憂いておしまいよ、と。

お金で解決できること(浮いたお金)だから今回現地調達したけど、 そもそも備えあれば憂いなしだからな!!

朝からSSAに赴きバッテリーを切らしたPの備忘録

つーかtwitterのバッテリー消費激しい。

Swift環境で定義するIBAction

Swift環境になってちょいちょい書き方が変わってわからなくなった点が増えた。

IBActionのつなぎ方について

パターン

  • コードでIBActionを書いて、UI部品と繋ぐ
  • UI部品からコードに差し込む
    • こっちのほうが良さそう

コードでIBActionを書いて、UI部品と繋ぐ

  1. @IBActionを頭につけたメソッドを作成する
  2. メソッドからUI部品に向けて、Ctrl+ドラッグで接続する

f:id:yajamon:20161003175248p:plain f:id:yajamon:20161003180214p:plain

UI部品からコードに差し込む

  1. UI部品の右クリックメニューから、処理を実行したいイベントを確認する
  2. メニューのイベントからコード上にCtrl+ドラッグで接続する

f:id:yajamon:20161003181607p:plain f:id:yajamon:20161003181617p:plain

所感

後者のほうが良さそう

理由

  • senderを補完してくれるから
    • f:id:yajamon:20161003193902p:plain