TaPL読書録 #1

2018年はmediumで記事を投稿しようと思っていたのですが、はてなブログのほうがなんだかんだ流入がいい気がしたので戻ってくることにしました。乗り換えのきっかけは、ブログのエディタの使い勝手があまりよくないことによっていたのですが、 kibela で書いてからコピペで貼ればいいや、という気持ちになって出戻りです。

mediumでは以下の3記事を書いていました。

『ふつうのLinuxプログラミング』 読了 – hkdnet – Medium

『白と黒のとびら』『精霊の箱』『自動人形の城』読了 – hkdnet – Medium

ある日 Entity Attribute Value に出会った – hkdnet – Medium

さて、今回の記事はTaPL読書録です。おそらくシリーズものになります。PFDS勉強会から派生してTaPL勉強会ができたのでそこでの疑問や得られた知識、派生して調べたことなどをまとめる予定です。1なお、記載内容に誤りがあった場合、原因の多くは私の理解不足であろうことを先に いいわけ 謝罪しておきます。 第1回は1, 2章が対象でした。ざっくりまとめると、型にまつわる概略とプログラミング言語とのかかわりが1章、集合などの数学的な基礎知識が2章でした。

ラッセルのパラドックスは、事前学習をしたのですが、wikipediaを見てもよくわからない状態でした。 R = { x | x ∉ x } という集合の定義をみたときに、 x は要素でありながら( x ∉ x の右辺)、集合である( x ∉ x )ということを考えると、 x が要素であるような集合の要素の集合の要素の集合の……と無限ループになってしまってとらえどころがなくて……。
という話をしたところ、右辺の x と左辺の x の「型」が違うはずなのに区別しないから矛盾が導けるよね、というのがラッセルのパラドックスであると教えてもらいました。

定義2.1.8
あまりにも関数に馴染みがありすぎること、関係というと関数が思い浮かびやすいことから案外つまづきました。部分関数の定義を読んでも、これは何であって何でないのか、というのがイメージしにくかったです。いまの私の理解では、「常に t1 = t2 である」が満たされないのは参照透明でない関係のことを指しているのだと思っています(例えばランダム性のあるものなど)。

定義2.2.1
s R t かつ t R s ならば s = t であるとき、Rは反対称的である というのは少しわかりにくいなーと思います。仮定部分の仮定では「s R t かつ t R s」で非常に対称的に見えるので。しかしその場合は「s = t である」という強い制約が導かれるので、ああたしかに反対称的と言われればそうなのかもな、という感じ。

定義2.2.3
上限と下限(結びと交わり)については「S = { 1, 2, 3 }, s = 1, t = 2のとき 結び j = 2」など具体例を挙げて確認しました。どうにも「結び」「交わり」という単語に苦手意識があるのですが、英語では "join" と "meet" らしいですね。そっちのがまだニュアンスがわかるような気がする。

演習2.2.6
反射的閉包の定義をみると「R を含む最小の反射的関係 R' のことである」とあります。 関係 R' を R' = R U { (s, s) | s ∈ S } とした場合に、R' が R を含むことは明らか。 U の右オペランドが反射的閉包の必要条件であることも明らか。 R の左右のオペランドである集合はそれぞれ何かの要素を抜いた瞬間に R' が R の反射的閉包であるための必要条件が満たされなくなるので、それらの和集合は最小であるといえます。

最初、反射的閉包のイメージが掴めなかったのですがイメージが掴めると、これ同じことしかいってねーなという感じ。

f:id:hkdnet:20180118014834j:plain

画像では R = { R1, R2 }, R' = {R1, R2, R3, R4, R5}です。関係とは図中の矢印の集合であるというのがわかればまあなんとかなるかと。

演習2.2.7
R0, R1, ... というのは下図のようなイメージ。点線をひいてあるところがその関係で追加されるところです。
f:id:hkdnet:20180118014806j:plain

演習2.2.8
推移的に追っていけばなんとかなるでしょ、という感じ

2章まではこんな感じでした。次回から本編に入るので楽しみです。


  1. と大風呂敷を広げましたがめんどくさくなったら派生して調べたことがなくなり疑問のまま放置されるでしょう。

2017年を振り返って

定量的な振り返りとしてGitHubの草を置いてみる。

f:id:hkdnet:20171231224923p:plain

3331 contributions
仕事とプライベート両方見えてるので結構すくなめかも。
一応草活は続いてる。

言語別のコーディング時間

f:id:hkdnet:20171231230323p:plain

定性的な振り返りとして隔月のことを思い出して適当に書く。

……予定だったんだけど1-6月のことを思い出すのがめちゃくちゃ難しいのでやめた。

今年一番のニュースは、うーん、やっぱり転職ですかねえ。
転職したことでいろんな人に会って、いろんなことを教えてもらって、世界が広がったなーと思いました。
具体的には Ruby コミッタの人と話すようになって、crubyのソースを普通に読むようになったことですね。
「やればできる」の幅が広がったのが嬉しいし、C言語とかを普通に読み書きできるようになりつつあります。
言語とかOSとかのレイヤまでちゃんと降りていって話ができるようになるよいきっかけだったと思います。

他には、いろんな知り合いが増えたのですが、新しい人と会うとなんとなく多面的になる気がしますね。
「ある人との関係性における自分」というのが人ごとにできるのでその分だけ。
そういう意味でしがないラジオ関連、特にずっきーさんとの交流ができたのは大きい気がしました。

昨年の振り返りを見てみるとこんな感じ。

  • ブログもっとかくぞ
    • ✗: 42記事 → 37記事
  • 定量的にはかれるようにするぞ
    • △: 作ったけどそんな使ってない

やはり大晦日に入れた気合はアテにならない……。

chrome拡張 OneTab が便利

Firefox 57が出た後、しばらく浮気をしていたもののなんだかんだあって結局 Google Chrome に戻ってきました。

思えば IE で育ったあとに unDonut を使い始め数年、10年くらい前にchromeの存在を知ったあとはずっと使い続けてきた一番のお気に入りソフトであるわけです。しかし、その長きに渡るインターネット生活を一変させる chrome 拡張に最近出会いました。

それが OneTab です。

chrome.google.com

使い方はかんたんで、いれたあとは「タブ多くなってきたなー」というときに押すだけ。
開いているタブ(のうちピン留めされていないもの)をすべてリスト化して1ページにまとめてくれます。
すげー単純なんですがこれが割りと便利です。

タブの整理をするときって、すでに狭くなってる中で要不要の判定をしていたので、それがわかりやすいタイトルで並ぶだけでも結構価値があります。
さくっと試せるのでいれてみてはいかがでしょうか。

Speee×Asakusa.rb Ruby2.5リリースパーティー に参加してきました

speee.connpass.com

行ってきました。
twitter に適当に投稿はしましたがだいぶはしょっているのでそれの補完を。

なんか別方面にささったらしく妙にRTされましたが。これはnobuがCentOS6で落ちるコードをコミットしたことをネタにしていたそうです。コミッタ同士の仲が良さそうで微笑ましいですね。

最初は Matz からの挨拶がありました。無事リリースできましたねーというところと反省点。

知り合いのコミッタも12月になってからも気合いれていろいろやっていて、11月にはもうフィーチャーフリーズしてるもんだと思ってたのですがそうでもないんだなあと思っていました。どうもコミッタ陣にとってもさすがにちょっと、という感じがあったようで2.6では余裕をもたせたいですねという話がありました。

Rubyユーザーにとっては 2.5 が出たばかりですが、コミッタ陣はもう2.6を見据えているようです。

github.com

こちらは当日の朝に投げられた k0kubun さんのPRです。これをネタに 2.6 で mjit をいれるぞー、はやくなるぞー、と盛り上がりました。

スピードネタでいうと、某メディアの記事で「3倍速い」という噂のRuby2.5なので1速度ネタが続きます。
Speee さんでのイベントの前にあった開発者会議では、 block.call 形式の場合にも safe level を考慮しないようにしてもよいという意思決定があり、よりはやく実行できるようになる見通しが立っているようです(ちょっと曖昧です)

このあたりから safe level や tainted など、知らない人もいるような機能の話に深掘りされていきました。個人的なお気に入りは mame さんが放った以下のフレーズ。

その他、2.5で強化されたカバレッジの話や binding.irb の話が続きました。

座談会の後の懇親会を細かにレポートしてもアレなのでこのへんで。
非常に楽しい会でした。ありがとうございました。


  1. 正確には、「ブロックを渡すが block.call のような呼び出しをしないときには Proc の生成をしないようにすることで3倍早くなる」だがなぜか見出しに「前バージョン比約3倍に高速化、Ruby 2.5.0がリリース」とあって、登壇者にネタにされていた

#しがないラジオ とキャラ付け

この記事は しがないラジオAdventCalendar 5日目の記事です。

adventar.org

すでに2回もゲストとして出演させていただきまして、自分のキャリアについては話しきった感覚があります。そのため今回はしがないラジオに出会って何が起きたのか、何を考えることになったのかということ書こうと思います。
転職ネタが知りたい方はどうぞ過去の sp3 と sp5 をどうぞ(宣伝

最初にぼくとガミさんの関係性を確認しておこうかと思います。
1年ほど前の僕にとってのガミさんは、小中高の同級生であり、ときたま酒を飲むような仲でした。どっかのSIerに就職したらしい1と思っていたのですが、いつの間にかweb系に転職することが決まっていて、そこからまた交流が増えた気がします。これがたぶん去年の9月くらい。Rebuild.fm の話をしたり、青春のアフター1〜3巻をガミさんにその場で購入させたりというイベントがあった喜ばしい飲み会でした。

その後の今年3月、 twitter を見ていたらいきなりガミさんが「podcast始めました」とツイートしていて大変驚いたのを覚えています。当時は Rebuild.fm チルドレンと呼ばれるように新規 podcast が登場したあとで、うわー俺もやりたいと思ってたけどめんどくさくて足踏みしてたのに、ガミさんはちゃんとやっていってるなあと思いました。

さて、そんなこんなでガミさんには先を越されてしまったわけですが、逆に自分で始めずにゲストとして出れば podcast に出たい欲を満足させつつ、定期的にやるのめんどくさいという気持ちに抗う必要もないことに気づくのにそう時間はかかりませんでした。雑に話させてよというと二つ返事でOKが出たのでゲスト出演が決まりました。

1回目のゲストのときは、特に深く考えずに今までのキャリアと、今何やってるかと、あと青春のアフターのおすすめをしようと思っていました。だいたいその通りになったと思います。
ですが続く2回目のゲストのときはいろいろ考えました。自身の2回目の転職というトピックはありますが、番組的にどう立ち回ろうかなあということを意識しはじめたのです。僕はパーソナリティの2人と比べると2年ほど長くこの業界にいます。また、しがないラジオへのフィードバックの中には「ガミさんとずっきーさんのキャラが似てる」というようなものがありました。

というわけで2回目のゲストの際には「自分の意見を強く主張する」ことを意識していました。

個人的な感想としては、ずっきーさんもガミさんもそんなに主張が強くなく(「〜〜って思ったんですよね、違うかもしんないけど」くらい)、また自分たちの考えたことや試してみたことが正しくないんじゃないかということを気にしているように感じていました。2
彼ら2人の意見に「それはそう」「それは違う」とはっきりいう役割が必要なんじゃないかと思って話そうとしていました。

結果的にはどうだったんでしょうか。
僕も彼らと同じで悩みながら生きていくタイプの人間なのでそれほど強く言えてないんじゃないかなーと思っています。反省点としては、ちゃんとやりきれなかったというより、違うキャラ付けを選んじゃったかなという感じ。

また話したいことが溜まったら33回目のゲスト出演したいと思っていますが、どういう風に話すか、あるいは素で喋るのか。しがないラジオに限らず今後のパブリックなアウトプットの方向性を考えたほうがいいのかも、という話でした。


  1. これはとても適切な表現で、ラジオで繰り返されるまでマジでどこだか覚えてなかった

  2. Reactの書き方の話のときにずっきーさんがそう言ってたような気もする

  3. すでにネタ帳は存在する

LOLIPOP! マネージドクラウド触ってみた

↑を見たので触ってみました。

マネージドクラウドの特徴としては以下の3つが挙げられています。

  • 自動セットアップ
    • いろいろプリセットが用意されてて選んだらポチで立ち上がる
    • 数秒で立ち上がるらしい
  • いつでもサイト表示
    • オートスケールのことっぽい
  • 常にセキュアな環境
    • セキュリティアップデートとかが自動だという意味

コンテナという単語が出てきているのでLXCをベースにしたなにかなのでしょう。

とりあえずメールアドレスとパスワードをいれて登録していきます。
登録するとプロジェクト作成画面に進みます。

f:id:hkdnet:20171202013320p:plain

そういえば登録した覚えがないけどアイコンついてますね。gravatar かな。
どうも下部を見ると Rails 推しっぽいので Rails にしておきます。

f:id:hkdnet:20171202013443p:plain

まだ灰色で選択できませんが hubot とかあって適当に chatbot をデプロイするのにもよさそうです。
プロジェクトURLがあるのでうれしいですね(って書いたけど heroku も OpenShift もあったわ)
ベータ期間なので無料だしクレカ登録もなく使えるのは嬉しいのですが、ベータが終わったらどんくらいのコスト感なのかは気になるところですね。

さて、プロジェクトを作成するとプロジェクトのダッシュボードにいきなり放り出されます。
ここたぶん何をどうすればいいのかわからなくなる人が多そうですね……。

とりあえず ssh するために ssh 公開鍵を追加しておきましょう。画面が単純なので割愛します。

というわけでプロジェクトトップに書いてある ssh コマンドを叩いてみるのだ

$ ssh -p XXX YYY@ZZZ
Last login: Fri Dec  1 17:02:43 2017 from 10.1.1.1
  __  __  ____   _          _ _
 |  \/  |/ ___| | |    ___ | (_)_ __   ___  _ __
 | |\/| | |     | |   / _ \| | | '_ \ / _ \| '_ \
 | |  | | |___ _| |__| (_) | | | |_) | (_) | |_) |
 |_|  |_|\____(_)_____\___/|_|_| .__/ \___/| .__/
                               |_|         |_|

******* Welcome to Lolipop! Managed Cloud *******

YYY@WWW:~$ pwd
/var/app
YYY@WWW:~$ ls
0000000000000000  current  shared  user_command.sh.sample
YYY@WWW:~$ ls current
Gemfile  Gemfile.lock  README.md  Rakefile  app  bin  config  config.ru  db  lib  log  package.json  public  test  tmp  vendor

普通にはいれますね。

オートスケールの設定はこんな感じ。

f:id:hkdnet:20171202233545p:plain

rails だとイメージ1個しかないんですね。nginx はさもうとかしたときにどこで何すればいいかはよくわからず。
とはいえたぶんそのへんってマネージドクラウドのサービス側でラウンドロビンとかはしてくれるんだろうなー。
static file の配信をうんぬんというのはいまんところ難しそう?CDN使えって感じかな。
ラウンドロビンするって考えると sticky な設定とかがあるのか気になります1

デプロイとかは medium にあるヘルプから察するに push すればよさそうです。
でも remote add したあとに push するだけだと --force いるんじゃないかなあ……。
という気持ちをもとにとりあえず git init して remote を追加した状態で fetch してみましょう

# local
$ git init
$ git remote add lolipop xxx # 表示されているやつをうつ
$ git fetch lolipop
fatal: '/var/lib/lolipop/projrepo/.git' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

実はまだリモートレポジトリは存在していなかったようです。
念のためマネージドクラウド側のコンソールでも確認

# managed cloud
$ ls /var/lib/lolipop/projrepo/
ls: cannot access /var/lib/lolipop/projrepo/: No such file or directory

仕方ないので rails new しておきましょう。
データベースを選んだ記憶はありませんがホスト名が mysql なのでおそらく mysql なのでしょう。

# local
$ bundle init
# Gemfile を適当に編集
$ bundle install --path vendor/bundle
$ bundle exec rails new --database=mysql .

database.yml もなんかいい感じに編集すればいいんじゃないでしょうか
記載内容はダッシュボードから拾ってきてください。

diff --git a/config/database.yml b/config/database.yml
index 0c61325..1a636b9 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -49,6 +49,7 @@ test:
 #
 production:
   <<: *default
-  database: tmp-rails_production
-  username: tmp-rails
-  password: <%= ENV['TMP-RAILS_DATABASE_PASSWORD'] %>
+  database: your_database
+  username: your_username
+  password: your_password
+  host: mysql-1.mc.lolipop.lan

password はベタ書きせずに環境変数にいれたくなりますがどーもその機構はない気がするので強い気持ちでコミットします

dbつかえるか確かめたいので適当に scaffold しておきましょう

$ bin/rails g scaffold Comment text:text
$ git commit -m 'comment'
$ git push lolipop master

と、これは別に意図してなかったのですがうっかり db:create, db:migrate を打つのを忘れてました。てへぺろ
なので db/scheam.rb は更新がない状態でデプロイされましたが db:create, db:migrate されたログが残って普通に起動しましたね

$ git push lolipop master
(中略)
remote: Database 'XXX' already exists
remote: == 20171202150523 CreateComments: migrating ===================================
remote: -- create_table(:comments)
remote:    -> 0.0046s
remote: == 20171202150523 CreateComments: migrated (0.0047s) ==========================
remote:

普通にアクセスできますね。

f:id:hkdnet:20171203004551p:plain

最初は、レスポンスが返ってくるまでに13秒くらいかかってましたが、dev tool開いたあたりからいきなり早くなりました。なぞい。
謎いなーと思いながらダッシュボードを見てたらコンテナ数が増えてたみたいです。

f:id:hkdnet:20171203005200p:plain

うんうん、そしたらはやくなるかもねって思ったのですが、コンテナの数が増えたからって1ユーザーのリクエストがそんな早くなるわけないですよね。
うーん、増えたコンテナに性能の善し悪しがあるのでしょうか?

あと適当にさわってるとときたま落ちます。落ちたときに ssh してログをみてみましょう。
適当にエスパーして $HOME/current/ が現在のアプリケーションだと考えるとその先の $HOME/current/log/production.log を見ればよさそうです。
vim が入ってるので適当にひらいておきます(less はなかった)

I, [2017-12-02T15:56:45.157297 #4]  INFO -- : [de41a671-8b69-4771-8c0e-83187b2c6456] Started POST "/comments" for x.x.x.x at 2017-12-02 15:56:45 +0000
(略)
W, [2017-12-02T15:56:45.159596 #4]  WARN -- : [de41a671-8b69-4771-8c0e-83187b2c6456] Can't verify CSRF token authenticity.
I, [2017-12-02T15:56:45.159979 #4]  INFO -- : [de41a671-8b69-4771-8c0e-83187b2c6456] Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
F, [2017-12-02T15:56:45.161589 #4] FATAL -- : [de41a671-8b69-4771-8c0e-83187b2c6456]
F, [2017-12-02T15:56:45.161650 #4] FATAL -- : [de41a671-8b69-4771-8c0e-83187b2c6456] ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

うーん、CSRF対策のトークンの検証で死んでますね。
たぶんなんですけど画面をレンダリングしたコンテナと違うところにいったら死ぬのかな……。

まとめ

現状での懸念点は以下でしょうか

  • 環境変数を管理するクチがない?
  • プロジェクトに対してミドルウェアを挟む余地が今のところなさそう
    • いずれちゃんと対応されそう
  • コンテナベースなんだけどライフサイクルがわからない
    • テクニカルなドキュメントが充実すれば……
  • デプロイ時に何が起きるのかブラックボックス過ぎて気になる
    • 知りたいし変更したい
  • そもそも ssh してる先ってどこなんだろ?
    • コンテナの中なの?コンテナのホストなの?
    • これもまあドキュメントが充実すれば
  • ssh先のディレクトリ構成がよくわからん
    • cap っぽい雰囲気を感じたけど
  • ログみたいときにいまのところ ssh するしかない
    • いずれちゃんと対応され……るのだろうか?
    • 他サービスに流しちゃうほうが楽かも
  • どんくらいのコスト感なのか知りたい
    • 有料化が決まる頃にはわかるので待つだけ

正直、いまのところはお手軽感よりブラックボックス感がつよい印象です。今後に期待ということで。


追記: つかったプロジェクト削除しようとしたらできなくて困っている……
削除確認用にプロジェクト名をいれたあとパスワードをいれても削除に失敗しました、と出てしまう。
変な文字列いれるとパスワードが違うと言われるので認証はできてるみたいなんだけど。
時間課金とかになるだろうから、削除リクエスト自体はこの時間で受けてほしいなーとおもいつつリソースはまだ使えちゃうからどうなんだろうなと思っている


  1. (フラグ

gitしぐさ 2017年11月編

最近の git コマンド運用録です。
雑に書いていきます。

前提

リモートレポジトリ戦略

常に以下の状態を維持します。

upstream: みんなの更新が集まってくるところ
origin: 自分の変更をいれるところ

なので例えば ruby/ruby のようなOSSだと fork 前提なのでこうなります。

upstream: git@github.com:ruby/ruby.git
origin: git@github.com:hkdnet/ruby.git

あるいは自分しか使わないプロジェクトだとforkできない(する意味もない)ので upstream と origin が一致します。

upstream: git@github.com:hkdnet/stdlinux.git
origin: git@github.com:hkdnet/stdlinux.git

一見無駄ですが、どのようなプロジェクトだろうと全く同じ操作ができるというのが強みです。

upstream から更新をとってくる

git fetch upstream でおk

ローカルで作業を始める

git checkout -b branch_name upstream/master

upstream/master からブランチを切ります。
ローカルレポジトリのmasterは存在する意味がないので強い気持ちで消しましょう。

ブランチ切るときは上記のでいいし、ローカルで最新版を見たいときも git checkout upstream/master で十分です。

pr出す前に upstream/master に更新がはいった

git fetch upstream はもちろんしてあるものとして、 git rebase upstream/master でおkです。
ちゃんとこまめにやってればそんなにコンフリクトしないでしょう。
したとしても気合で解決を試みて、ダメなら git rebase --abort でやめればいいので気軽にやっています。

pushする

git push origin head です。
headは現在のブランチ名として解釈されるのでどんなブランチ名のときもこれでおkです。


なんか他に操作あったっけ……。思い出したら書きます。