System Preferences → Notifications → “When mirroring to TVs and projectors”にチェックを入れてプレゼン中に通知が出ないようにしましょう。
(僕は念の為、通知センターからもチェックしています)
ありがとうスティーブ。
System Preferences → Notifications → “When mirroring to TVs and projectors”にチェックを入れてプレゼン中に通知が出ないようにしましょう。
(僕は念の為、通知センターからもチェックしています)
ありがとうスティーブ。
Reactでちょっとした計算機を作ろうと思い、せっかくなのでStorybookを試してみることにした。
GitHub - aereal/delay-time-calc
BPMとフィードバックさせたい音の音価を入れるとディレイタイムがミリ秒で出力される。
BPM 120で8分ディレイをかけたかったら250msec.にすればいい、みたいなことが手軽に計算できる。
いま触って気付いたけど付点8分のときの計算まちがっている気がする……。
create-react-appで雛形を作り、Storybookのドキュメントを読んでセットアップをした。
TypeScriptでstoryを書くのに一手間必要だったが、ものはできた。
変更内容は以下の通り。自動生成するコマンドの実行結果と手作業で加えた変更はコミットを分けているので、わりとわかりやすいのではないかと思う:
https://github.com/aereal/delay-time-calc/compare/94b844e12a73fd91b52d21a542b3566e19ab9151...eb106a6dda7e606a40de1453a56d4e642554ae14
TypeScriptでstoryを書くためのあれこれは typescriptでReact Storybookを試す。 - Qiita が参考になった。
HTTP::Request#content($bytes)
もしくは HTTP::Request#add_content($bytes)
を呼んでもcontent-lengthは自動で計算されず、0になる。
なのでそのままリクエストを送ると、ちゃんとcontent-lengthだけbodyを読む実装はボディが空だとみなすのでちゃんとcontent-lengthを計算しなければいけない。
Plackの実装に慣れていたのでびっくりした。
my $req = HTTP::Request::Common::POST($url); my $json = JSON::XS::encode_json($payload); $req->content($json); $req->as_string;
HTTP::Request#as_string
した結果:
POST http://example.com/api/issuance Content-Length: 0 Content-Type: application/json {"status":"success","expires_at":"2018-04-09T12:19:26+09:00"}
Content-Length: 0
になっていることが確認できる。
aws cloudformation package
はS3にfunctionとかいいかんじにアップロードして、そのARNが埋められてそのまま aws cloudformation deploy
実行可能なテンプレートを出力してくれる
--output-template-path
id:dekokun ++
参考:
外部ライブラリの例としてaws-sdk-goを使ったこういったコード例を考える:
type CertificateFetcher struct { client *dynamodb.Client } func New(client *dynamodb.Client) *CertificateFetcher { return &CertificateFetcher{client: client} } func (f *CertificateFetcher) GetCertificate(domain string) (string, error) { resp, err := f.client.GetItem(...) if err != nil { return "", fmt.Errorf("...") } key := resp.Item["key"] if key == nli { return "", fmt.Errof("...") } }
DynamoDBと通信させずにエラーのハンドリングや *dynamodb.GetItemOutput
から値を取り出す処理などについてテストしたいが、そのためには *dynamodb.Client
を差し替える必要がある。
実装を差し替える範囲が広すぎると実際に実行されるコードに対するカバレッジが低くなりテストの意味がなくなるので、適切な境界を見つけてそこで差し替えられるとよさそう。
実際にどうやるか、結論としては CertificateFetcher
を *dynamodb.Client
ではなく必要なメソッドが定義されたinterfaceに依存させるとよい。
例:
type DynamoDBClient interface { GetItem(item *dynamodb.GetItemInput) (*dynamodb.GetItemOutput, error) } type CertificateFetcher struct { client DynamoDBClient } func New(client DynamoDBClient) *CertificateFetcher { return &CertificateFetcher{client: client} } func (f *CertificateFetcher) GetCertificate(domain string) (string, error) { resp, err := f.client.GetItem(...) if err != nil { return "", fmt.Errorf("...") } key := resp.Item["key"] if key == nli { return "", fmt.Errof("...") } }
テストコード例:
func TestGetCertificate(t *testing.T) { stubClient := &StubDynamoDBClient{} fetcher := New(stubClient) // ... } type StubDynamoDBClient struct {} func (c *StubDynamoDBClient) GetItem(item *dynamodb.GetItemInput) (*dynamodb.GetItemOuput, error) { // ... }
Goのinterfaceは所与のメソッドを実装していれば特別なアノテーションをつけずとも構造体がinterfaceを実装しているとみなされるので、実装を変更できない外部ライブラリに対してアドホックにinterfaceを定義できるので便利。
このようにインターフェースに依存させてDIしやすくするというのは、たとえばScalaにおけるcake patternなど他にも例があります。
参加した。酔った勢いで参加登録し、新幹線と宿を予約をし、東京は吉祥寺に舞い降りました。
ライブと仕事でしか東京に行かないので西のほうに行くのは新鮮。
設計というテーマもさることながらしんぺいさん (id:nkgt_chkonk) を見に行くチャンスなので京都から参加登録した。
設計という抽象的な話題についてうまく他人とコミュニケートできる・それだけのプレゼンテーションができるというのはすごいことだと思っている。
参加して設計についてもちろん深い考察が得られたらいいと思っていたけれど、それ以上に自分が感じる「設計についていいかんじに他人にプレゼンテーションするために必要な能力は何なのか」について手掛かりが得たいと思っていた。
結論から言うと、それは得られた。簡単にまとめてみると:
……という能力およびそれの効果的な発揮に裏打ちされているのだと理解した。
具体的には:
……という風に表れている。
「今あえてDRY原則に向き合う」というスライドはよかったです。
こうして考えてみるとティーチングに対しても問題解決の原則を持ち込んでいるということであって、目新しさはない。ないが、当たり前のことを当たり前にやるということを実践できることは非凡ではないと思う。
京都からいきなりやってきたけど非常に楽しく参加させてもらえてありがたかったですし、個人的にはインターネットで見かけたおもしろそうな人を見に行くために出かけるのはインターネット原体験っぽさがあってよかった。
終電がなくなって吉祥寺から宿をとった京橋までタクシーに乗ったら「京橋? (舌打ち)」って言われたり「京橋ってどこですか?」って言われたり、深夜の急カーブ高速道路を120km/hで駆け抜けて恐怖を感じたり久しぶりにメチャクチャな目にあったけどそれもよかった、また吉祥寺いきます。
Go向けのデバッガで、ステップ実行とかブレイクした行のレキシカル変数が見えたりといった基本的な機能を提供しつつ、dlv debug
でコンパイルしつつ実行 (go run
) したりgo(1)とほどよく統合されている。
後述するheadlessモードがあっていわゆるリモートデバッグが可能。
公式のドキュメントではbrew install go-delve/delve/delve
一発で済むように書かれているが実際はうまくいかなかった (´°̥̥̥̥̥̥̥̥ω°̥̥̥̥̥̥̥̥`)
==> Installing go-delve/delve/delve ==> Downloading https://github.com/derekparker/delve/archive/v1.0.0.tar.gz ==> Downloading from https://codeload.github.com/derekparker/delve/tar.gz/v1.0.0 ######################################################################## 100.0% security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain. ==> Generating dlv-cert ==> openssl req -new -newkey rsa:2048 -x509 -days 3650 -nodes -config dlv-cert.cfg -extensions codesign_reqext -batch -out dlv-cert.cer -keyout dlv-cert.key ==> [SUDO] Installing dlv-cert as root ==> sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain dlv-cert.cer Last 15 lines from /Users/aereal/Library/Logs/Homebrew/delve/02.sudo: 2018-02-28 11:11:35 +0900 sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain dlv-cert.cer If reporting this issue please do so at (not Homebrew/brew or Homebrew/core): https://github.com/go-delve/homebrew-delve/issues These open issues may also help: Upgrade to delve fails https://github.com/go-delve/homebrew-delve/issues/20
紹介されているissueを見てみると証明書を生成してインポートするスクリプトを手で実行したらうまくいったと書いてある。
実際に実行した手順はこういうかんじ:
✘>﹏<✘ < cd $(brew --cache)/ ✘╹◡╹✘ < tar xzf delve-1.0.0.tar.gz ✘╹◡╹✘ < cd delve-1.0.0 ✘╹◡╹✘ < bash ./scripts/gencert.sh ✘╹◡╹✘ < brew install go-delve/delve/delve
delveをインストールしたら sudo pkill taskgated
を実行してtaskgatedを再起動する。
プロセス間通信を監視するデーモンらしく、bash ./scripts/gencert.sh
で生成・インポートした証明書を読み込みしなおす必要がある。
Visual Studio Codeは便利、GoやTypeScriptを書くとき最近はもっぱらこれ。
vscode-goというGoを書くときの各種便利サポートを追加してくれる拡張を入れる。
Debugging Go code using VS Code · Microsoft/vscode-go Wiki · GitHubが詳しい。
Visual Studio Codeでリポジトリを開きつつ Debug → Open Configurations でデバッガの設定 (JSON) を開く。
設定中の mode
を remote
にする。remoteにすると別プロセスで既に起動しているデバッガーに接続する。
Debugging Go code using VS Codeにあるように、シェルで dlv --listen=:2345 --headless --
などと実行してデバッガーを起動する。
あとはVisual Studio Codeの Debug → Start Debuggingを押すとデバッガー開始できる。
行頭を押すとブレイクポイントを設定できまるでIDEのよう〜。
ステップ実行もできるしレキシカル変数も見れて便利!!!!
rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*
してないか確認する。
コンテナのプロビジョニングを試行錯誤しているときに docker-compose run --rm app bash
とかやりがちだけど、最初の方に apt-get update && apt-get install && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*
しているとaptのキャッシュもリポジトリも消えるので、あるべきリポジトリが見つからないように見えることがある。
探すときはpackages.debian.orgを見るとかするとよい。
スクリプトで自動化したいときは困る。
そういうときは unzip -o /path/to/kure.zip
のように -o
オプションを使うとよい。
-o overwrite existing files without prompting. This is a dangerous option, so use it with care. (It is often used with -f, how- ever, and is the only way to overwrite directory EAs under OS/2.)
- Fix mirror() (haarg) #9
https://metacpan.org/changes/release/MIYAGAWA/LWP-Protocol-PSGI-0.10#L4
changesには `LWP::UserAgent#mirror` についてのみ言及があるけど、`get()` メソッドの `:content_file` 引数にも影響がある。
`mirror` メソッドも `:content_file` 引数も紆余曲折あり `LWP::Protocol#collect` を呼ぶことでレスポンスボディがファイルに保存される。
fix LWP::UA::mirror calls by haarg · Pull Request #9 · miyagawa/LWP-Protocol-PSGI
上記Pull Requestはつまるところ適切に `collect` を呼ぶようにする変更なので、 `mirror` も `:content_file` も適切に処理される、ということだった。
昨年末からぼちぼち書いている。
……を目的に考えて日記を書くためのブログシステムを書きはじめた。
Web技術で遊び続ける定まった場所がないと、技術を使うための技術の域を出ない学習が続くなという問題意識から何か作ることにし、自分はWebでテキストを書くのが大好き人間なので、ブログシステムを作ることにした。
それでも自作するか
ブログシステムは自作すべきか? ブログサービス VS 自作システム | tech - 氾濫原
もしウェブプログラマなら自作すべきであると常に主張したい。
自分もこの意見に賛成で、まあブログシステムであることにこだわらなくてもいいけれど、趣味なら車輪の再発明など恐れずにとにかく遊び続けるのがいいと思う。
また完全無欠のASP型のサービスなどありえないわけで、その点では自作するとき自分が求めていてASPサービスにないものを作れるならば、それは完全な車輪の再発明とはいえないし、得るものは大きいと思う。
パフォーマンスチューニングを目的に挙げているのは、仕事でもWebアプリケーションを作っているがそもそもパフォーマンスについて考える時間が少ないので知識も技術も身に付かない、けど求められるものではあるというギャップを埋めるためでもある。
そしてこうした興味・好奇心だけを目的とせず、使う自分自身の満足度・快適さに対する解決の手段として自分の興味がある技術を選べるような題材という点でも、ブログシステムは適している。
ソフトウェアエンジニア一般が趣味の開発でこうしたモチベーションでいるべきと考えているわけではなく、単に自分が趣味で作ることを考えるとき自分がよく使うもので、かつうまく動いていると自分が一番に喜ぶものでないと、継続して触りつづけるモチベーションが保たないだろうということを見越した、合理的な理由による。
インフラはGoogle Cloud Platform、configuration managementを考えるのがだるいのでランタイムはコンテナに任せようということでk8s (GKE) を選んだ。
仕事でAWSを使っているので、では趣味ならGCPというくらい。あと料金計算が明快なのがいい、AWSはリザーブドインスタンスとか考えはじめると勘定がめんどう。
いまVPSに月におよそ1000円くらい払っているので、これを解約することを見越してプラス勉強代として月2000円まででやりくりしようと思っている。
パフォーマンスチューニングを深追いしたいということで、ポピュラーになったCDNは採用せず自分でリバースプロキシを運用することにした。
サーバサイドはRuby, DBはPostgreSQL, 記事の編集画面はTypeScriptで書いている。
インフラとフロントエンドが弱いと感じていて、そちらにリソースを割きたいのでサーバサイドは使い慣れたRubyにした。
Rubyはぱっと作ることができて安定感があるものの、型がなかったりもうちょっと冒険してもいいかなと思っている。
とはいえパッケージ管理とかでむやみにハマっていたくないし、予算上、ホストのメモリとかは潤沢にはできないのでScalaは選びづらいし、仕事でも趣味でもGoをよく書いており食傷気味なので、やはり落とし所として妥当かと思っている。
本当はサーバサイドはホットスポットではないのでGAEにしてもよかったんだけれども、予算の都合でStandard Environmentしか使えず、StandardだとJavaかPythonかGoかPHPで、どれも気乗りしなかったのでGKEにした。
フロントエンドはそのうちSPAにしてみたい。
昔、仕事でSPAを触っていたけどhistory APIにバグのある地獄みたいな環境向けだったので、今のまともなブラウザと充実してきたと思われるライブラリ類で、リソース管理などの煩雑さが減ったのかそうでもないのか確かめてみたい。
いまは最低限、記事を書いてそれを配信するところまではできたのでGKEにデプロイしようとしている。
Kubernetesは耳慣れない概念がたくさん出てくるので難しいけど、GCPのドキュメントが充実しているのでチュートリアルを見様見真似でやりつつ要件・予算にあわせてあれこれ手探りで変えて試している。
sudo mkdir -p /opt/mackerel-agent/plugins sudo chown -R $(id -un):$(id -gn) /opt/mackerel-agent/plugins mkr plugin install aereal/mackerel-plugin-macbook-battery-health@v0.0.2 cat <<EOS >> /usr/local/etc/mackerel-agent.conf [plugin.metrics.macbook_battery_health] command = "/opt/mackerel-agent/plugins/bin/mackerel-plugin-macbook-battery-health" EOS
以前作ったプラグインを `mkr plugin install`-readyにした。
対応といっても命名規則を整えてGitHubにリリースしたくらいで非常に手軽で便利。手順はMackerel公式のドキュメントが詳しくてわかりやすい。
実際に対応するための変更は以下のPull Requestにまとまっている。ちゃんと読んでいなくてzipじゃないとダメとか命名規則とかが適合していなくて無駄にトライアンドエラーを繰り返してしまった。
バッテリ残量の監視はなにかと便利なのでどうぞご利用ください。
r7さんらの振り返りがおもしろかったので自分も書き出した。
5,184 JPY/year
過去作から最新作までたくさん配信されているのでなにか見たいな〜という時に便利。
最近はテレビ放映とタイミングを揃えて配信される作品が増えたのでほんとうに良い時代になった。
今は京都という割と地上波のチャンネルに恵まれた地域に住んでいるけれど、地元は北海道なので深夜アニメがまったく見れずに悲しい思いをしてきたので、地域差が縮まるのは歓迎。
配信の仕組み自体は素朴という印象で、AmazonプライムビデオやNetflixと違いビットレートを調節してバッファリングの時間を減らすとかそういう取り組みはしてなさそうなので、ネットワークの品質に問題があるとストレスを感じることもある。
3,900 JPY/year
お急ぎ便などなどに使っている。あとプライムビデオのラインナップが絶妙で、dアニメストアと補完しあったり昔見たおぼえのある映画をたまに見ている。
9,492 JPY/year
いつのまにかDeveloper planだとprivateリポジトリの上限がなくなってますます便利になった。
スケッチとかIntelliJの設定 (自動でコミットされるのでまずい内容が出てしまわないか心配なのでprivateにしている) などとりあえずprivateでも作っておけるという安心感を買っているようなもの。
26,640 JPY/year (6GB ライトスタートプラン)
数年前にauからMNPしてずっと使っている。京都で生活していると人が多くて遅いというようなこともなく快適。
もともと3GBのプランだったけれど旅行で外に出る日が続くとすぐにクーポンを使い切ってしまうので6GBにした。
44,352 JPY/year → ?
一人暮らししてから家の回線はWiMAXを契約しておりその流れで今も使っている。
……が、いまは通信量に上限があり、それはよいとしても課金して制限を解除する道も提供されていないので潮時かなーと思いしばらく立つ。
固定回線は、それはそれで地域において品質の良いISPを見つけること、工事に立ちあう必要があること、などから二の足を踏んでおりいまだにどうしようか考えるがまあいいかな……と思う。
次に引っ越すことがあったら諦めて固定回線を契約すると思う。
11,760 JPY/year
Lightroomなど使うために入っている。
11,760 JPY/year
ポピュラー音楽のラインナップは特に琴線に触れるところはないけどクラシックのラインナップが満足できる。
聞きたいオーケストラの盤が揃っているので好きな時に聞き比べたり参考にできるので気に入っている。
1,080 JPY/year
旅行で東海道・山陽新幹線やJR西日本の特急に乗る機会が増えたので契約した。
会社で出張するときは会社が契約しているEX-ICで新幹線に乗るのだけれど、あれを知ったら直前まで予約が変更できる便利さなしでは生きていけない。
のぞみに1回乗った時の割引額が1,080円なので1年に2回乗ったら回収できるのでかなりお得だと思う。
あと海外旅行前にVISAではなくMASTERCARDのカードを手に入れる目的もあった。
(解約) → 11,400 JPY/year
「ヴァイオレット・エヴァーガーデン」「からかい上手の高木さん」の配信がNetflixだけだったので再度契約した。
バッファリングの短さとか視聴するときのストレスのなさは使ったことのあるサービスの中では一番だと思う。
21,384 JPY/year → 10,692 JPY/year
1GBプランを2つ契約していたけど1つにした。
Elasticsearchとか計算機リソースを使うミドルウェアで遊ぶ時は、リソース単価の安いVPSのほうが使い出がある。
16,800 JPY/year → 1,047 JPY/year (予定)
古い写真のRAW画像の保存にGlacierを、このブログなどなどのドメインのネームサーバとしてRoute 53を使っており、これで年1,047円くらい。
……のつもりだったのだけれども、昨年明けに検証のために立てたEC2インスタンスを落とし忘れていて昨年1年間ずっと毎月10USDかかっていたことがわかって慌てて解約した。
6,000 JPY/year → 解約
家計レポートとか見れたらおもしろいかなと思って契約したけど既に述べたようにEC2のインスタンスを起動しっぱなしで気付かないような人間なので、まずMoneyForwardにお金を払う前にやるべきことがたくさんあることに気がつき解約した。
EC2インスタンスを起動しっぱなしにする人間は何をやってもダメ。
年 | 金額 | 前年比 |
---|---|---|
2017 | 483,040円 | 124.09% |
2016 | 389,277円 | 124.54% |
2015 | 312,547円 | 136.27% |
2014 | 229,352円 | - |
カメラやレンズなどは含んでいない。主に Kindle 本や生活用品など。
この調子でいくと来年は45万くらい年間で使う目測だけど、そんなに成長するかな、どうかな。
数字で振り返った2016年 - Sexually Knowing
順調に124%成長が続いている、すごい。後で紹介するように給与は毎年110%ペースくらいなので、いつか追い付かれる。
入社して以来、給与明細をGoogle Driveに保存してあり、支給額 (手取り) を12掛けして年俸額とした。
なので年俸額なのにやけにピコピコしている。
営業期が変わるタイミング (1月と7月) に人事評価がありそこで報酬が変わるので、だいたいそのタイミングで大きく変わる。
グレードという給与レンジを定めた概念が全6段階あって、それが変わるとベースも変わるのでそこで大きく変わる要因はそれくらいと見える。
いちおうグレードは役職と関係ないということになっている。
ちなみに控除額も有史以来記録してあり、見るとげんなりするもののひとつ。
年 | 記事数 | 前年比 |
---|---|---|
2017 | 53 | 72.60% |
2016 | 73 | 486.7% |
2015 | 15 | 13.0% |
2014 | 115 | - |
一転、減ってしまった。1月に大雪があったりクロアチア旅行に行ったり前半はよく撮ったし、後半も撮っていないこともないけれど上げていく気力がなかった。
9月から今もずっと仕事で完全に頭が参ってしまっている。書いていたらなんで仕事に忙殺されてこんな虚しい振り返りをしているんだとイラついてきた。
年 | 記事数 | 前年比 |
---|---|---|
2017 | 87 | 55.76% |
2016 | 156 | 91.22% |
2015 | 171 | 54.11% |
2014 | 316 | - |
ほぼ半減した。9月くらいから本当に気が参って「仕事やめたい」とか「1000万ほしい」としか書いてない下書きがたくさんある。
近しい人に読んでほしくないので接続元のIPが地理的に近かったら見れなくするとか、そういうことをしたいな。