休んでいる時にたまに見たりしてしまい無闇に疲れていたので消してしばらく経つ。
緊急の連絡はDMでやりましょうって合意できているし、DMはメールでも通知が来るようにしているので、ひとまず困らないだろうと思っているけど、実際どうかはわからない。
あとグループウェアにも気軽にアクセスできないようにしたいけど、それはちょっとめんどうそうで悩む。
休み中に疲れが溜まる要因を減らしていきたい。
休んでいる時にたまに見たりしてしまい無闇に疲れていたので消してしばらく経つ。
緊急の連絡はDMでやりましょうって合意できているし、DMはメールでも通知が来るようにしているので、ひとまず困らないだろうと思っているけど、実際どうかはわからない。
あとグループウェアにも気軽にアクセスできないようにしたいけど、それはちょっとめんどうそうで悩む。
休み中に疲れが溜まる要因を減らしていきたい。
だいぶ大仰なタイトルでありますが掲題の内容を社内勉強会で話しました。
音楽を作る古典的な方法論 (機能和声) を取り上げ、その中でも和声 (harmony) をコアドメインと見据え、実際に和音進行の規則などを実装したという内容です。
和声と周辺の概念をScalaで表現したコードを交えながら、和音や調・音階をエンジニア向けにどういうパラメーターを受け取ってどのように導出できるか、といった観点で紹介しています。
端折ったりやや正確さに欠ける説明になっているところがあると認識していますが、プログラミングあるいは抽象的な構造とその生成規則を発見するという観点でおもしろさを感じてもらえるようなアレンジです。
紹介したコードは素朴なWebアプリケーションとして実装し、公開しています: GitHub - aereal/music-study
アカデミックな知識を師事したりきちんと学んだことはないのですが、ピアノを弾き始めたころからずっと学んできた分野で、プライベートワークもいくつか作っています。
一方、プログラミングを始めてからしばらくして、ものごとを抽象化して似た特徴や規則を発見するおもしろさを見出してから、たとえば和音の特徴付けは音程 (周波数比) で決まるよなとか、音楽や音楽を作り上げるルールたちをプログラミングや数学の語彙を使って述べ直すことができそうだなということはずっと頭の中にありました。
ちょうど社内勉強会の順番がやってきて、最近は業務に直結した話が多くマンネリを感じていたので、ハッタリを効かせる意味と自分に発破をかける意味で「自動作曲」というワードで取り組むことにしました。
実際にコードを書き始めたのは10日前くらいでいけるやろと思っていたけど後述する点にハマるなどし、動くものができたのはギリギリだったのでだいぶ焦りました。
なにせ発破をかけるために大仰なタイトルをつけたのに、蓋を開けたら動くものはなにもありませんでした、だと顔向けできないので……。
普段の業務範囲からだいぶ離れたドメインを扱うので退屈に感じないかなあという心配もしていたのですが、思ったより反響があったことには救われました。実際、こういうことが考えられるよねという実装を提示してワイワイ議論が起こったらいいなと目論んでいたので、そういった意味では成功したといえます。
毎週開催のはてな社内勉強会、本日は「機械学習アプリケーションの管理」と「Scalaで自動作曲の練習」の二本立てでした。意外と音楽に一家言あるエンジニアも多く、Slackの実況が盛り上がってました! pic.twitter.com/7lzzY9K9bv
— hatenatech (@hatenatech) 2017年9月14日
当初は12平均律を前提として、周波数を実装に使っていたのですが数値の精度が足りなくてテストが落ちはじめた時は、進まない進捗と共に絶望的な気持ちになりました。
Rationalに切り替えていくのも大変だったので、動くものを作ることを重視して、物理的な実装に寄せる作戦は諦めました。
また種々の概念は一見すると規則的で実装しやすく見えたのですが実際はそうでもなく、ある言葉が指す概念が非常に曖昧あるいは広すぎてユビキタス言語を発見するのに戸惑いました。
たとえば音程の完全1度、短2度、長3度、増1度みたいな名前は、一見すると「修飾子」+「N度」という構造をとれるのではないかと思うのですが「N度」という概念は五線上の距離を指す一方、修飾子は半音上げたり下げたりといった音高に作用するものなのでドメインが異なり表現が困難です。
音程は結局、半音の数で表すこととし、半音の数が6つの場合はDiminishedFifth, AugmentedFourth, あるいはTritoneという名前で参照できるということにしました。
12平均律が前提であればこれでよいのですが、音律に依存せずN度の表現ができると望ましいと感じているので今後改善していきたいところです。
Web Audioなどを用いて実際にこのソフトウェア実装から生成した和音進行を耳にできるようにして、そこから実装されていない規則を追加していきたいですね。
また、和声といいつつ和音進行しか実装できていないので、せめて声部配置くらいは実装したいし、できていて然るべきかなと思っています。
プレゼンテーション内で短三和音を誤って「長三和音」としていた点を修正しました。
社内グループに書いていたメモをせっかくなので放流します。
リモート勤務するなら本格的にディスプレイや椅子を揃えて環境を作らないと自分はやりづらいということがわかった。
あるいはMacBook1枚とインターネットさえあれば砂漠でも仕事できるという強靭な心身を手に入れるか。
あと通勤が苦ではなく、むしろデスクワークに終始しがちな毎日において貴重な身体を動かす機会と捉えていた節がある。
天候が悪かったり、どうしても自宅にいない用事が発生したら、柔軟に自宅で勤務できる会社なので、いまのところ自分はリモート勤務そのものに対するこだわりは無いかなあと思った。
むしろオフィス勤務だと福利厚生としてディスプレイとかいいオフィスチェアを用意してもらえるので、そういう点を考えると自宅勤務はけっこう非効率だなあと感じた。
リモート勤務メモ - Sexually Knowingb.hatena.ne.jpリモートワークなのにオフィス時間割に合わせてる????
2017/08/29 17:28
労働形態の話と勤務地の話は別なので、コアタイムがある時は勤務地がどこであろうと合わせるべきと思います。
という形式的な話もありつつ、物理的に同じ空間にいないからこそ朝に挨拶するなどして不在かどうかを発信することも、同じ空間にいない時に他のメンバーに不安を与えないために重要だと思って時間は特に意識して守るようになりました。
Goで実装する軽量マークアップ言語パーサー - builderscon tokyo 2017
buildersconは初参加。ぼちぼちパーサーを書いていたのでいい機会だと思って応募し採択されてこの度初ビルコンで話してきた。
60分枠でひとりで話すのは初めてで時間配分にとても悩んだ。なんとか20分×3みたいな構成にしようと思ったけど前半は抽象的な話が多かったので眠くなってしまったかもしれない。
仕事とは関係なく作り上げたものについて話をするのは、ずいぶん気が楽だし自信を持てることだったなあと思い出した。仕事は自分ひとりの成果といえるものはごく少ないし、自分は抽象的な話をするのは苦手だ。
特におもしろかったトークについて。
まず、基本オフレコなので感想を書けないのがとても残念だけど、オフレコという縛りがあるのも納得の前夜祭のトークはどれも強烈だった。
DeepLearningによるアイドル顔識別を支える技術 - builderscon tokyo 2017
id:sugyanさんのアイドルの顔認識の話。
アイドルの顔の系統が似通っていて識別が大変という話がおもしろかった。たしかに年代が近くその時代でかわいいとされる顔立ちの人がなるものと考えると頷ける。
自撮りの角度が決まっているのでそれを学習してしまいたまに違う角度で写っていると判別できないことがあるという話を聞いて、いわゆるハナザーさん (花澤香菜) アングルがある話を思い出した。
小さく始めて育てるコンパイラ - builderscon tokyo 2017
id:rhysdさんのコンパイラを作っていく話。多相型の推論アルゴリズムがいくつかあるということも知らなかったのでまさに「知らなかった、を聞く」だった。
おもしろそうだったので自分もコンパイラを書いてみたい。
コピー通りWeb系に囚われないトークがたくさんあって刺激的だった。あとスピーカー弁当はじめ供出いただいたフード類がおいしくて嬉しかったです。次もなにか話したい。
あとめっちゃいい杓文字いただけました。
最近、セキュリティに特に気をかけなければいけないサービスの開発をしていて調べた知見のメモ。
Subresource Integrity - Web security | MDN
いわゆるチェックサムの仕組み。 integrity
属性に ${hashalgorithm}-${hashdigest}
形式の値を書いておき、フェッチしたファイルのハッシュ値が一致していなければブラウザが読み込みをブロックする。
これは、たとえばCDNが攻撃されるなどしてスクリプトなどが改竄された場合に有効。
JSやCSSはプリ・ポストプロセッサで処理し出力することがほとんどだろうが、subresource integrityとどうやって統合するかというとgulp-hashsumを使ってコンパイルしたファイルのハッシュ値をdigest.jsonに保存し、HTMLのレンダリング時にそれを参照してscript/link要素に埋める、という方法が考えられる。
開発しているサービスは、使っているツールセットなどの兼ね合いからこの方法をとっている。
インタラクティブな要素が少ないので、Plackミドルウェアで一律 default-src 'none' style-src 'self'
を指定した後にホワイトリスト形式で追加するという運用にしている。
これでいくつかハマった点があるので紹介。
Google Tag ManagerはHTML断片やGoogle Analyticsなどのタグタイプを選べるが、これはつまるところ動的なスクリプトの実行・読み込みなので script-src
などのポリシーが適用される。
上記のようなホワイトリスト形式のポリシーと相性が少し悪い。
動的なスクリプトの実行については、都度nonceを付与するということも考えられるけど、ホワイトリスト形式で運用したいページではそもそも使わないのが手間を考えると楽かと思う。
外部スクリプト読み込みは、諦めてタグタイプを追加する度にポリシーに追加することにした。といってもGoogle Analyticsくらいしか使わないだろうから、そんなに困っていない。
Content-Security-Policy: default-src 'self' http://example.com http://example.net; connect-src 'none'; Content-Security-Policy: connect-src http://example.com/; script-src http://example.com/Is a connection to example.com allowed or not? The short answer is that the connection is not allowed.
Content Security Policy Level 2
たとえばデフォルトは厳しいルールを指定しておくが、エンドポイントごとに緩めたい時はデフォルトのポリシーをレスポンスヘッダから取得しマージした値をレスポンスヘッダに再度書き出すということが必要。
※やまなし、いみなし、おちなし
Web広告は目にするとイラつく
街頭広告はそうでもない
テレビCMはイラつく
WEB広告は有限のリソースを浪費されているかんじがする
ページと関係ないと→ネットワークリソースや表示領域が浪費された
ページと関係あると→広告とそうでない情報を区別する労力が浪費された
なぜ広告を区別する必要があるか
広告は情報価値の期待値が低い
なぜ低いと感じるか
一般的な情報は外部の指標によりフィルタリングされる (Google, SNSの反応)
広告は入札の仕組み以外にフィルタリングの仕組みが存在しない
→ 一般的な情報を評価するのと広告が広告であるのか判断するのとで、労力が変わっているのか気になる
テレビCMがイラつくのも恐らく同根
時間が奪われる
街頭広告はなぜイラつかないのか
浪費されるリソースが無限に近い
壁面は無限 目を背けられる
歩いているときは情報を求めていない → 価値の低い情報を見ても区別したり評価する必要がない
最近思うところあってAtomでコードを書く時間を増やしている。
といっても普段書くPerlはこれまで通りVimで、趣味でTypeScriptを書く時にAtomを使うようにした。
Vimの使い勝手に慣れ切ったつもりだけど、昨年一年間はIntelliJでScalaを書く時間が多かった。それが思いの外に馴染んだので、もしかしたらVim以外でもなんとかなるのでは? と思い、まずは趣味の時間からちょくちょく使いはじめることにした。
Vimは設定をGitで管理してけっこう設定に凝っている。道具を自分の手に馴染むように変えるスタイル。
対してAtomで書く時は、あまりカスタマイズせず、キーボードショートカットも覚えずにGUIでぽちぽちすることにしている。
いままで設定を練ったVimよりできることは減ったり手間がかかるようになったはずだけれども、耐え難い感じはしない。
むしろGUIがリッチなので便利に思う時が多い。
クライアント (ブラウザ) とサーバーがやりとりするためにgrpcを使えないかなと思ってサンプルコードを見たりちょっと触ったメモ。
結論からいうと今回の用途には合わないので見送ったけど、後のために。
Can I use it in the browser?
Not yet. This is an area that's being actively explored and we welcome feedback and contributions. We are collecting names of people interested in early access program here. There is node.js support for server side JavaScript.
grpc / FAQ
WebアプリケーションのレスポンスヘッダにGitのsha1を含めておくと、デプロイに失敗していて古いバージョンだった (そのせいでおかしかった) ということに気がつきやすくなって多少便利。
Perl (PSGI) だと、 `git rev-parse HEAD > VERSION` などしておいて Plack::Middleware でファイルの内容を読んで `Plack::Util::header_set` と `Plack::Util::response_cb` で用が済むけれど、Scalaはコンパイル時にいろいろできそうな気がしたので調べた。
sbt-buildinfoというsbtプラグインを使うとプロジェクト名やバージョンなどの情報を含むcase objectのコードを生成してくれる。
Usageより:
lazy val root = (project in file(".")). enablePlugins(BuildInfoPlugin). settings( buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion), buildInfoPackage := "hello" )GitHub - sbt/sbt-buildinfo: I know this because build.sbt knows this.
`build.sbt` にこう書いておくと `hello.BuildInfo` に `name` や `version` が埋められたcase objectを定義するコードが出力される。
sbt-gitというsbtプラグインを使うとプロジェクトのバージョン文字列をGitのコミット情報から生成することができる。
`git describe` を使うようにするとか、自分でsha1を加工する (e.g. 先頭8文字だけを使う) ことができるので使い勝手がよい。
タグは使っていないのでsha1の先頭8文字を埋めるようにしている。
lazy val root = (project in file(".")). enablePlugins(GitVersioning). settings( git.formattedShaVersion := git.gitHeadCommit.value map { sha => sha.substring(0, 8) } )
Action.async { implicit request => val result = ??? result.withHeaders("x-version" -> app.BuildInfo.version) }
こういうかんじ。
僕はコーヒーが苦手で、飲むと必ずお腹を壊すので避けるようにしている。
その代わりではないけれど、気分転換したいときには紅茶を淹れて飲むことが多い。
コーヒーと違って蒸らし時間があるので待ち時間がどうしても発生する。ティーバッグを淹れてそれを処分する関係上、自席にも戻りづらい。
そこで腹筋ローラーの出番となる。
もともと学生時代と比べて筋肉の衰えが気になりはじめたので買ってオフィスに送ったのだけれども、持って帰るのが面倒で置きっぱなしにしていた。
あるとき、ふと思い立って紅茶を蒸らしているあいだに腹筋ローラーをしてみたらちょうどいい時間だったので、これ幸いとしばらく続けている。
紅茶の蒸らし時間はだいたい2分くらいで、慣れていないうちは10回腹筋ローラーするだけでもそれくらいの時間がかかる。
数回続けると慣れて素早くできるようになってくるので、成長と共に蒸らし時間あたりの回数が増えていって、ティータイムと共に成長の実感が得られて思わぬ喜びがあった。
腹筋ローラー、1オフィスに1台オススメです。
Soomloom アブホイール エクササイズウィル スリムトレーナー 超静音 腹筋ローラー エクササイズローラー 膝を保護するマット付き
HTTP APIのキャッシュ戦略を考えながら、ふとcache-controlなどを指定しなかったとき、デフォルトのキャッシュ戦略はどのように定義されているのか気になったので調べた。
RFC7234のStoring Responses in Cachesにレスポンスをキャッシュしてもよい条件が述べられている。
A cache MUST NOT store a response to any request, unless:
RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching
- The request method is understood by the cache and defined as being cacheable, and the response status code is understood by the cache, and
- the "no-store" cache directive (see Section 5.2) does not appear in request or response header fields, and
- the "private" response directive (see Section 5.2.2.6) does not appear in the response, if the cache is shared, and
- the Authorization header field (see Section 4.2 of RFC7235) does not appear in the request, if the cache is shared, unless the response explicitly allows it (see Section 3.2), and
- the response either:
- contains an Expires header field (see Section 5.3), or
- contains a max-age response directive (see Section 5.2.2.8), or
- contains a s-maxage response directive (see Section 5.2.2.9) and the cache is shared, or
- contains a Cache Control Extension (see Section 5.2.3) that allows it to be cached, or
- has a status code that is defined as cacheable by default (see Section 4.2.2), or
- contains a public response directive (see Section 5.2.2.5).
(マークアップは筆者による)
まず1つ目でHTTPメソッドがcacheableであるかとある。特に言及はないけどRFC7231で定義されている。
this specification defines GET, HEAD, and POST as cacheable, although the overwhelming majority of cache implementations only support GET and HEAD.
RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
注意したいのはPOSTもcacheableである点。「ほとんどの実装は対応していないけどね」と但し書きされているが、明示しておくに越したことはなさそう。
巡り巡ってRFC7231のSection 6.1で定義されている。
Responses with status codes that are defined as cacheable by default (e.g., 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, and 501 in this specification
RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
501 Not Implementedはキャッシュ可能と定義されているので、5xxがキャッシュされないという認識でいると注意が必要かもしれない。
range付きリクエストのレスポンスのキャッシュ戦略については別途述べられているが、必要としなかったので読んでいない。
nginx の ngx_http_auth_basic_module を使って BASIC 認証をかけることができる。
ドキュメントを読むと明示的に `auth_basic off` を指定することで BASIC 認証を切ることができそうだったので試したけど、うまくいかないケースがある。
結論からいうと `auth_basic off` は上位のコンテキストから継承した設定を打ち消すためのもので、同じコンテキストで指定された `auth_basic` は打ち消せない。
実際のコード例:
# app.nginx.conf server { server_name app.example.com; include "/path/to/config/auth.nginx.conf"; # 同じコンテキストで auth_basic が指定されている auth_basic off; # 祖先コンテキストではなく同じコンテキストなのでダメ }
auth.nginx.conf:
auth_basic "Authentication Required"; auth_basic_user_file "/etc/nginx/conf/auth.htpasswd";
実際に config test を行うとエラーになる:
nginx: [emerg] "auth_basic" directive duplicate in app.nginx.conf:5 nginx: configuration file /etc/nginx/nginx.conf test failed
これはドキュメント中の以下の文章で示されている:
The special value off allows cancelling the effect of the auth_basic directive inherited from the previous configuration level.
http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic
プライベートで締切のあるタスクや、忘れてはいけないタスクは To Do 管理ツールでリマインドしている。
それらのようなタスクは、誰かに依頼されるだとかして具体的なタスクとして直接インプットされる一方、日々の生活における夢はたとえば「石油を掘り当てたい」といった曖昧でふわっとしているし、なんなら実現可能性なんてものを考えていない。
ふとした瞬間に省みると、自分が細々としたルーチンを繰り返す生活の奴隷に思えることがあってげんなりする。
しかし自分はまだまだ生活に夢や希望を抱いていて、壮大とはいえぬものの少なくないそれらを支えにして生きているわけだから、目に見えるようにしておくと楽しいのではないかと思って夢を集める場所を作った。
それがタイトルにあるとおり Trello のボードでその名も「生活の夢」。
Trello にした深い理由はなく、たまたま楽しい気分で Trello を見ていたら思いついただけ。
ルールや運用なんてものは存在せず、ただ思いついたときに思いついたことを書いていくだけ。達成したら Done に移す。
達成したタスクを捨てたりせずただ Done と名付けられたリストへ移動するやり方は、カンバンに由来するもので、叶った・叶えた夢が集まってくるというところがとても楽しい。
最近は「テレビを買う」という夢を叶えた。「テレビを買う」ことがなぜ夢たりえたかというと、あると楽しいだろうけれど必要というわけではなく、そのわりに高いのでどうかと思っていたから。贅沢ともいう。
世の中においては理性的な振る舞いが求められるので、この Trello の前では自分の欲望に素直になろうと思います。
オーディエンスとして参加したので聞いたトークのメモなど。
主に Web アプリケーションの世界におけるキャッシュの話。目新しい話題ではないけれど、キャッシュは本質的にむずかしい話題だし、よくまとまった内容なのでこれからキャッシュの戦略を考える際の議論に役立ちそう。
「パターンに名前を与えると、名前を使って認知し議論できます」という話がよかった。確かにどれもよくあるパターンだけど、普段会話するときは「get_or_set 的なやつで……」みたいな表現をしがちだったので、名前をつけることだけでもとても意義のある内容だと思う。
後日 id:moznion さんと個人的に会話して Varnish の話をするなど、発表をもとに会話が生まれる技術カンファレンスの原体験みたいなことが起きて、そういう意味でもいいトークだったなーと思う。
いい話聞けたし、最近自分も Varnish を触っているので YAPC::Fukuoka 2017のトークに応募しようかな、と思った。
www.slideshare.net
別のところ (社内だったかも?) でも「ServerlessってつまりCGIじゃん」みたいな話を聞いたので、静かに普及しつつある見解っぽい。
Microsoft Azure Functions のランタイムが公開されているところは後発ならではでよいなと思った。
parse.com 終了は対岸の火事だったけど、このトークを聞きながら何度か自分のことのように肝が冷えることがあって、臨場感のあるトークだった。
撤退の作戦を考える際に DNS のレイヤからアプリケーションのレイヤまで検討できるだけのエンジニアがいるチームだからこそ切り抜けられたのかもなあ、と思った。小さいチームっぽいけど、いいエンジニアが集まっているチームという印象を受けた。
あとこういう内容だとともすればヘイトばかり撒き散らしがちだけど、ケーススタディとして具体性があって役立ちそうだし、parse.com へのリスペクトを欠かしていなくて建設的で聞いていて安心感があった。
Google スプレッドシート、プログラマブルであるという意味でエンジニアにも受け入れられていて、良くも悪くも「エクセル」はもはや表計算ソフトではなくて「エクセルなんだなあ……とか思った。
イベントでものすごいスパイクがやってくるとか、カラムにサイズの大きなデータを入れていて転送量が逼迫するとか、心当たりのあるできごとが多くて他山の石感があった。
マスターデータとコードでは、コンフリクト解決の方法や頻度が違うので別リポジトリにしているのはなるほどってかんじ。
15年の歴史をご紹介という内容。
こうして俯瞰してみるとコンウェイの法則のお手本みたいだなーと思った。人が増えてきて効率化のために Ridge のようなフレームワークが生まれ、さらに増えて人の多様性が増すと実装としてのフレームワークが薄まる揺り戻しが起きる、というような。
気付いたときには懇親会のチケットが売り切れていて、それだけが個人的に残念であったものの、イベントとしてかなり濃い Perl トークが多くて楽しかった。
次回は福岡で、温故知新にかけて未来をテーマとのこと。福岡観光したいしトーク応募考えます。
git log \ --grep 'Revert' --invert-grep \ # revert コミットを除く --diff-filter=A \ # 新規追加のみ --format='' --name-only \ -- lib/Plack/Middleware
lib/Plack/Middleware/
以下に最近ファイルを新規追加したコミットの一覧:
lib/Plack/Middleware/IIS7KeepAliveFix.pm lib/Plack/Middleware/IIS6ScriptNameFix.pm lib/Plack/Middleware/LighttpdScriptNameFix.pm lib/Plack/Middleware/Head.pm lib/Plack/Middleware/Recursive.pm lib/Plack/Middleware/HTTPExceptions.pm lib/Plack/Middleware/BufferedStreaming.pm lib/Plack/Middleware/Dechunk.pm lib/Plack/Middleware/Log4perl.pm lib/Plack/Middleware/LogDispatch.pm