読者です 読者をやめる 読者になる 読者になる

ごらくらいふ

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

検索に使った正規表現はMarkdownにでも書いて残すと良い

気がする。

特定のリポジトリでしか使わない検索内容だったので、同じリポジトリの中にregexps.mdを作って書いた。 使い方も一緒に書いておけば忘れても大丈夫だ。

こんな感じで。


Match parameter name for obj-c

(:\([^()]+?\))[^:\s]+?(?= [a-zA-z]+?:|$)
Example
// Base
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

// Erase matched-word
- (BOOL)application didFinishLaunchingWithOptions

// Use $1 when replace.
- (BOOL)application:(UIApplication *) didFinishLaunchingWithOptions:(NSDictionary *)

手元の録画データをバックアップするときに選ぶAmazonのクラウドストレージサービスはGlacier? Unlimited Drive?

Mac Book Airを買ってから最近放置気味のデスクトップPC。

1TBもあったストレージがいつの間にか残り100GBと少し。 ところがインストールしたプログラムもホームフォルダ以下も大して消費していない。なぜか。

f:id:yajamon:20161103140735p:plain

答え) C:/直下にあるプレイ動画の録画ファイルが犯人だから。

録画はちょちょいとエンコードしたら実質不要。でも消すのはもったいない。

→そうだクラウド環境に保存しよう

頻繁に取り出すわけでもないし、Amazon GlacierとAmazon Unlimited Driveを比較してみた。

Amazon Unlimited Drive

料金

  • 13800円/年
    • 1150円/月

Amazon Glacier

料金

ストレージ使用量
  • $0.0114 : GB/月
    • 100GBで約1$ => 約100円
    • 1TBで約1$ => 約1000円

結論

1TBを超える予定ならAmazon Unlimited Drive。 (使い勝手の面からもこっちでいいやという気持ち)

ファイル数や解凍関係で料金の変動はあれど、ひとまず月額の容量単価基準で答えは出た感ある。

EntyのPayPal自動支払いがいつまでたっても停止しないのでPayPalでキャンセルした

大体の経緯

キャンセル問い合わせの流れ

PayPalのお問い合わせフォームにて以下を送信。

以下の自動請求IDについて、支払い期日がYYYY/MM/DDの分から受け付けられておりません。 自動請求ID

onetapが提供するサービスについても、同時期から提供を受けることができず、請求だけが加算されております。

サービス提供者に問い合わせても音沙汰がないため、Paypal様からキャンセルをお願いいたします。

PayPalから自動返信メールが届くので以下を返信。

PayPal

頂きました下記の例では解決いたしません。 お手数ですがご対応をお願いいたします。

2日弱くらいで返事Paypalからキャンセル処理の通知メールと、返信が届く。

心理的負担からの解放

健やかに月を跨げるようになった。

自分の.vimrcをgistからダウンロードする

gist idやraw_urlを目視確認してからcurlするのは人間のすることじゃない、ということで。

前提

  • jqが使える
  • curlが使える
  • gistにある.vimrcはpublicである
  • .vimrcはちゃんと.vimrcという名前にしている
  • 複数.vimrcがある場合は、一番ファイルサイズの大きい.vimrcを信頼する

結論

# curl https://api.github.com/users/yajamon/gists | jq 'map(.files | select(has(".vimrc"))) | max_by(.[".vimrc"].size) | .[".vimrc"].raw_url' | xargs -n1 curl > .vimrc

URL listをcurlにパイプで渡してダウンロードしたい

jqでURL取り出してCurlに引き渡したかった。(しかも1件だけ)

curl (標準出力 OR パイプ)」とかでggってもPostするデータをtextからとかそんなんばっか。

結論

# cat url_list.txt | xargs -n1 curl

xargsコマンドを使って指定したコマンドを並列実行させる - 技術メモ帳

xargsの使い方を探しに行ってやっと見つけたんだけど、この情報のたどり着けなさ、みんなマジで困らなかったの…?

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

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

条件設定

あるコレクションのメソッドにて、引数の識別子に一致する要素を探し、仕事をさせる。 この時、引数が存在しないとき(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

参考リンク