kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

Dependency Injection 依存オブジェクトの注入 についてのおぼえがき

Dependency Injectionって「依存性の注入」じゃないの?

やっていることは、 依存しているオブジェクトを注入するようにする なので、「依存オブジェクトの注入」の方が訳としてただしいのでは? という議論がある

little-hands.hatenablog.com

あと、自分が読んでいるオブジェクト指向設計実践ガイドでも「依存オブジェクトの注入」が採用されているので、こちらを使う

依存オブジェクトの注入 ってどういう時の使うの?

依存性が高いオブジェクトを内包している時。そのオブジェクトを外部から注入するように修正する

具体的にはこんなコード(オブジェクト指向設計実践ガイドより)

class Gear
  attr_reader :chainring, :cog, :rim, :tire
  def initialize(chainring, cog, rim, tire)
    @chainring = chainring
    @cog = cog
    @rim = rim
    @tire = tire
  end

  def gear_inches
    ratio * Wheel.new(rim, tire).diameter
  end
  # ...
end
Gear.new(52, 11, 26, 1.5).gear_inches

このコードのどこが問題なの?

ギアのインチを計算する Gear#gear_inches が、Wheel依存した状態 である

結果的に以下のような問題が発生する

  • 変更時のコストが高い
    • 例えば Wheel.new のためだけに、rimtireGear#initialize に渡されている。そのため、Wheel.new の引数が変わったら、Gear は大幅に変更が必要になる
    • そもそもここに Wheel があることを知らなければ、修正が必要なことにも気が付けない
  • 再利用性が低い
    • Wheel 以外のオブジェクトからギアを計算したい時、別のメソッドが必要
  • テスト実装のコストが高い
    • テストを書く時に、Wheel オブジェクトのことを考慮する必要がある

じゃあどんなふうに直したら良いの?

こんなふうに、Gear に対して外部から、diameter を呼べるオブジェクトを注入してあげれば良い

class Gear
  attr_reader :chainring, :cog, :wheel
  def initialize(chainring, cog, wheel)
    @chainring = chainring
    @cog = cog
    @wheel = wheel
  end

  def gear_inches
    ratio * wheel.diameter
  end
  # ...
end
Gear.new(52, 11, Wheel.new(26, 1.5)).gear_inches

こうすれば、 Gear は、Wheel に依存しなくなり、 wheel については #diameter さえ実行できればどんなオブジェクトでも良くなる → ダックタイピング

なので、Wheel が変更されてね影響は少なくなるし、テストするときも簡単な mock を作れば良いだけになる

蛇足

むしろ、「依存性オブジェクトの排除」とか言ったほうが意味が通じそう、という話を会社のQiita::Teamでした

DynamoDB の capacity unit おぼえがき

概要

  • read/write capacity unit という単位でユーザがテーブル毎にcapacityを設定する
  • 実際の使用量とは関係なく 設定した、read/write capacity unit に比例した金額が請求される

capacity unit とは

1 capacity unitは、以下の通り

write

1秒に1回 1KBの書き込み

read

以下のいずれか

  • 1秒に1回 4KBの強力な整合性のある読み込み
  • 1秒に2回 4KBの結果整合性のある読み込み(書き込みが反映されないことがある)

参考: 読み込み整合性 - Amazon DynamoDB

補足

  • writeもreadもサイズを超える場合、それだけ capacity unit が消費される
  • capacity unit以上の通信が発生した場合、蓄積されて開くまで待たされる

capacity unit の料金

25 read/write capacity unit/month までそれぞれ無料

それ以降は、東京リージョンなら以下の通り

  • write: 0.000742USD/1capacity unit hour
  • read: 0.0001484USD/1capacity unit hour

reserved capacity

1年or3年単位で read/write capacity を先払いすることで割引を受けられる

最低単位は 100 capacity unit/hour

参考

Firefox で「サーバが適正な中間証明書を送信しない可能性があります」という表示が出た時に見るページ

あるいは中間証明書の解説

f:id:kasei_san:20180817183111p:plain

原因

中間証明書 がサーバにupされていない

中間証明書ってなあに?

証明書3階層の中間にある証明書

ルート証明書 → **中間証明書** → サーバ証明書

証明書の証明ってどうやっているの?

上位の証明書の公開鍵で電子署名を複合することで、正しい証明書かチェックしている

電子署名 is 何?

証明書の本文のhash値を、発行局の秘密鍵で暗号化したもの

電子署名を使った証明書の証明の流れ

  1. 発行局の証明書(中間証明書)をダウンロード
  2. A.発行局の公開鍵で、電子署名を複合
    1. 証明書の本文のhash値を取得
  3. AとBが一致していることを確認

なお、中間証明書の証明のためには、最上位のルート証明書の公開鍵が必要

ついでに、ルート証明書について

予めブラウザに入っている世界で信頼できるとされている認証局の証明書

ルート証明書は自分の秘密鍵電子署名を作成している(オレオレ証明書)

中間証明書の補完について

ほとんどのブラウザでは、サーバに中間証明書が無くても、勝手になんとかしてくれる

  • 証明書のAuthority Information Access 拡張フィールドに、中間証明書のURLが書かれている
  • これを見て中間証明書を取ってきてくれるらしい

当然対応していないブラウザや、curl などではセキュリティ警告が出る

「俺の環境では動いた」系問題なので厄介

第六種オレオレ証明書

正規の証明書だが中間証明書はupされていない状態

高木浩光先生が命名

第六種オレオレ証明書

正規の認証局(中間認証局)から取得したサーバ証明書であるが、中間認証局の証明書をサーバに設置していないため、クライアントが認証パスを検証できないもの。

高木浩光先生は今後は増加してくのではないかと予測している

(ブラウザで補完してれるので、気づきづらいため)

Docker For Mac の docker build で `no space left on device` した時の対策

原因

docker for mac仮想マシン上で動いているが、その仮想ディスクの容量がいっぱいになると発生

対策

prefarence で仮想ディスクのサイズを変更する

画面上、変更できないように見えるけど、クリックしたら普通に変更できた

f:id:kasei_san:20180808104401p:plain

f:id:kasei_san:20180808104422p:plain

ただし、今回はディスクリセットで対応

f:id:kasei_san:20180808104436p:plain

余談

仮想ディスクをクリアしたら、フォーマットが Docker.qcow2 から Docker.raw に変わった

  • なお、仮想ディスクのありかは ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.raw

最近 raw フォーマットになったらしい。こっちのほうがスループットが良いらしいですよ!

円記号問題の歴史

円記号問題の歴史をまとめました

ISO/IEC 646 の誕生

元々、文字コードの国際規格 ISO/IEC 646 では 0x5C は国ごとに自由に設定してよい領域 だった

  • アメリカ(ascii) では、 0x5C をバックスラッシュ
  • 日本(JIS X 0201) では、0x5C¥

アメリカで 0x5C を特殊な用途に使う例が発生

  • MS-DOSでは、0x5C をディレクトリ区切り記号
  • C言語などでも、 0x5C をエスケープシーケンス等の制御コードに

なんでわざわざ国ごとに異なる文字を特殊な用途つかうの...

そのため、日本では 0x5C に2つの意味が...!

  • 円記号
  • ディレクトリ区切り記号やエスケープシーケンス等の制御コード

日本で SHIFT_JIS が生まれる

  • JIS X 0201 ベースなので、0x5C¥ のまま

欧州で文字コード規格 ISO/IEC 8859-1(Latin-1) が作られる

  • ¥0xA5

世界の文字コードを統一すべく、unicode が生まれた

  • U+005C は バックスラッシュ
  • ¥ は、U+00A5

windowsのunicode対応が始まる

  • SHIFT_JIS(windowsだとcp932) から、unicodeに変換するときどうしよう?
    • ¥ に2つの意味があるため、単純な変換はできない

そうだ! 💡 0x5C0xA5¥ を表示しよう💡

  • なおキーボードで ¥ を入力すると 0x5C が入力される

そして悲劇へ...

日本語版windowsで円記号を入力しても、他の環境ではバックスラッシュに見える

見た目上バックスラッシュか円記号かわからないので、コードを書く時に混乱したり予期せぬエラーが発生する

参考

srad.jp

naruse.hateblo.jp

misspell で無視したい単語をgitで管理する方法

スペルチェッカー misspell。超便利なのでみんな使いましょう

github.com

前提

misspell では、-i オプションにカンマ区切りで、スペルチェックを無視する単語を追加できる

misspell -i "hoge,fuga" .

やりたいこと

misspell のチェックを無視する単語を git で管理したい

  • スペルチェッカー的には間違いだけれど、いろんな経緯で使わざるを得ない単語とか

解決方法

  • 無視する単語を .misspell_ignore.txtに保管
  • そのファイルで -i オプションを作るスクリプトを組んだ

ファイル

.misspell_ignore.txt

hoge
fuga
  • 1行1単語(差分をわかりやすくするため)

./script/misspell.sh

#!/bin/sh
misspell -i `cat .misspell_ignore.txt | tr '\n' ','` -error .
  • .misspell_ignore.txt の中身をカンマ区切りに変換して -i オプションに渡している

これで、無視したい単語をgitで管理できる!! 🎉

CircleCIで使いたい場合

checkout してから、上記のスクリプトを実行する

  misspell:
    docker:
      - image: nickg/misspell
    steps:
      - checkout
      - run: ./script/misspell.sh

workflows:
  version: 2
  ci:
    jobs:
      - misspell

参考

kakakakakku.hatenablog.com

Dockerのディスクioがボトルネックになる原因とその対策

dockerのディスクのマウント先がループバックデバイスだと遅い

ストレージドライバがaufsだと遅い

ただし現在はデフォルトでaufsが選択されることはほぼない → Docker = AUFSという図式はもう忘れたほうがいいかもしれない、あるいはDockerとストレージドライバの話 - Qiita