Rails MVCしか知らなかったバックエンド開発者が、最近のフロントエンド開発を学んで得た知見


これは、これまでRailsの古き良きMVCな開発体制しか知らなかったバックエンド開発者が、環境が変わってフロントエンド開発を学ばざるをえなくなった者の記録です。

歴史的に正しい事実を書いたものではなく、私個人の理解を整理するための妄想日記です。

 

私はこれまではWebアプリの開発ばかりやってきて、RailsでHTMLテンプレートエンジン使ってviewを作るスタイルでしか開発してきませんでした。

 

f:id:ksss9:20210221232753p:plain

しかし、ネイティブフロントとWebフロント両方があるアプリケーションが開発されているところを見て、ある事を思いつきました。

 

「Webフロントもネイティブフロントのように開発できれば、バックエンドエンジニアはバックエンドに、フロントエンドエンジニアはフロントエンドに分業できて、開発しやすくなるのでは?」

 f:id:ksss9:20210221232937p:plain

この気付きが超重要でした。このイメージを持てたおかげでフロント開発の意義がスルスル入ってきました。

 

Railsフルスタックフレームワークなので、RailsでHTMLを生成して返すことができますが、その開発体制だと、「バックエンドエンジニアは、得意なバックエンドを沢山書いて、不得意なフロントエンドをちょっと書く。フロントエンドエンジニアは得意なフロントエンドを沢山書いて、不得意なバックエンドをちょっと書く。」ということが起こっていたように思います。

だんだんと、「ちょっと不得意な人が書いたコード」が増えていきます。レビューで指摘しあえれば良いのですが、なかなか完璧にはいきません。

 

もし、RailsのV部分を引き剥がして、フロントエンドが得意なエンジニアに開発を任せることができれば、RailsAPIだけでよくなり、ネイティブフロントもWebフロントも同じようにAPIを提供する形で開発できます。

 

どうやらこれを実現するのがSPA(シングルページアプリケーション)という事なのかなと思います(多分間違ってる)。

だからこそRailsAPIモードができたり、PWAだとかいう話が出てきたのかなと想像します。

 

そしてSPAを作りやすいReactやVueが盛り上がったと予想します。このSPAをS3とかなんかいい感じのプラットフォーム(これがNetlifyとかなのか?)にデプロイすれば、サーバーを管理せずとも簡単なアプリなら作れるし、Lambdaとかと組み合わせれば結構なことまで出来ちゃいます(これがAWS amplify?)。いわゆるLinuxサーバーを立てたりしなくてもマッシュアップサービスとかが作れてしまうので、サーバーレスとかも叫ばれてきたのかなあ?

 

このSPAも細かく言うと色々やりようがあるようです。

 

例えばブラウザでページを開いたときにJSが起動してHTMLを構築するシンプルな方法をCSR(クライアント サイド レンダリング)と言うそうです。だいたいのことはCSRで行けるし、create-react-appが出てきて学習コストも下がってきたので、今も結構使われてるのかなと予想します。

 

しかしながらGoogleクローラーがJSを実行するかしないか微妙な時期があったのか、最初のJS実行時のラグを気にしてか、サーバーサイドでReactなりVueなりを実行してHTMLを生成する手法が出てきました。これがNext.js(React)とかNuxt.js(Vue)ということかなと思います。これがSSR(サーバー サイド レンダリング)と言うそうです。

 

Next.jsの方をちょっと触っただけですが、動的画像生成を実装した経験からも、next/imageだけでもかなり便利そうです。

これは、libvipsを使って動的に画像を生成して、ブラウザ毎に最適な形式でファイルを作り、キャッシュ用のヘッダーもいい感じにして、なんなら専用サービス(Vercel?)にデプロイすれば生成したファイルをキャッシュしてくれます。

これだけでも導入する動機になりそうです。触ってみた感じ、S3のファイルとかでもドメインさえ設定すればなんでもいけそう。

ただし、この画像生成機能はビルド時ではなく画像へのリクエストがサーバー上に来たときだけに使えるので、SSRでは使えても後述するSSGでは使えないようです。

 

さて、そんなSSRも、GoogleクローラーがJSを実行してくれるようになったり、CDNが一般的になったり、そもそもサーバー側の要素が増えるので、実装が複雑になってしまいがちでした。そこで新たな策として、予めビルド時(デプロイ時)にDBなりを見てもいいからHTMLを生成しておいて、これをCDNなりで静的ファイルを配信すれば、サーバーのプロセスもいらないし、なんならDBもいらないし、既にレンダリングされているから表示も早いしでいい事ずくめとなったのがSSG(スタティック サイト ジェネレーター)なのかなーと予想します。

これがNext.jsの今の売りっぽいです。CSRに似ていますが、HTMLのあらかじめ生成度合いが、CSRが0だったのがSSGで80〜100になったイメージです。もちろんAPIをクライアントサイドから叩いて動的コンテンツを追加することもできます。なんかこの辺からJamstackと言うらいしいっぽい感じがします。ブログとかほとんどSSGでいけそうです。

 

更にISGやISRなんてのもあるっぽいですが、まだまだキャッチアップ中です。。。 

 

さてさて、こんなことを最近学んでみて、また、少しNext.jsアプリケーションを作ってみて、昔ながらのRailsアプリケーションに対する考え方が変わり、ようやく時代に追いつけてないことが自覚できたレベルにはなれたかも?と思いました。

これまで作ってきたものは、サーバーサイドでほぼ同じHTMLを作って返すものなので、最近のフロント事情からしたら無駄が多いのかもと思えてきました。

また、Next.jsをcreate-next-appで作ってみると、驚くほど簡単にコンテンツが作れてしまいます。フロントはからっきしだった私が、簡単なアンケートサイトみたいなやつなら作れたので確かです。

Next.jsはルーティングも簡単に(ファイルパスを切るだけ)できるので、最早VもCもフロントでできてしまいます。

そして、どうせSSRするなら、そのnodeサーバーからprismaなりでDBを叩いて動的コンテンツを返せれば1プロセスだけでいいし、認証もFirebase AuthenticationやAuth0なんかで作れてしまいます。

そうなると「もはやRailsはいらない!」みたいな思考になる人が現れてもおかしくないなと思う気持ちも理解できます。

もちろんRailsでHTMLを生成する方法も、状況によってpros/consあるかとは思いますが、自分が見ないようにしていたものの大きさを急に知って、驚くばかりです。

っていうかもはや私としては、バックエンドエンジニアとは?自分の存在価値は?みたいな気持ちです。

 

これから、改めて「どうやってアプリを作るのか」を考え直してみたいと思います。

entrykitがM1 mac(Apple Silicone)で実行できないときの対処法

現状

M1 macでDockerのApple M1 Tech preview 7 *1 を動かしています。

golang:1.15 imageがたまたま手元で動いていたのでこれで試します。

entrykitはv0.4.0のバイナリを配布していますが、これを実行しようとすると以下のようにgoレベルで落ちてしまい実行できません。

$ docker run --rm -it golang:1.15 bash
root@aa08b9d02add:/go# wget https://github.com/progrium/entrykit/releases/download/v0.4.0/entrykit_0.4.0_Linux_x86_64.tgz
root@aa08b9d02add:/go# tar -xvzf entrykit_0.4.0_Linux_x86_64.tgz

root@aa08b9d02add:/go# ./entrykit
runtime: failed to create new OS thread (have 2 already; errno=22)
fatal error: newosproc

runtime stack:
runtime.throw(0x84a820, 0x9)
    /usr/local/go/src/runtime/panic.go:527 +0x90
runtime.newosproc(0xc820026000, 0xc820035fc0)
    /usr/local/go/src/runtime/os1_linux.go:150 +0x1ab
runtime.newm(0x8e5980, 0x0)
    /usr/local/go/src/runtime/proc1.go:1105 +0x130
runtime.main.func1()
    /usr/local/go/src/runtime/proc.go:48 +0x2c
runtime.systemstack(0xa2b6e0)
    /usr/local/go/src/runtime/asm_amd64.s:262 +0x79
runtime.mstart()
    /usr/local/go/src/runtime/proc1.go:674

goroutine 1 [running]:
runtime.systemstack_switch()
    /usr/local/go/src/runtime/asm_amd64.s:216 fp=0xc820020770 sp=0xc820020768
runtime.main()
    /usr/local/go/src/runtime/proc.go:49 +0x62 fp=0xc8200207c0 sp=0xc820020770
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc8200207c8 sp=0xc8200207c0

あまりパソコンに詳しくないのですが、 downloadしたものはx86_64(amd64)環境のbuildと思われるので、aarch64(arm64)環境では動かないのかなと推測します。

また、entrykitは長らくreleaseされておらず、作者も興味を失っている気がする(憶測)。

界隈で一瞬流行ったので、なんとなく使われているということが多いのではないでしょうか。

考えうる解決法

解決方法はいくつか考えられます。

1. entrykitを捨てる

そもそもprehookだけの利用の場合、entrykitは必要ありません。

prehookコマンドの正体は、

$ prehook ① -- ②

となっている場合、

  1. ①を外部コマンドとして実行する(複数可)。その後②でexecする。
  2. --以降がなく①だけの場合は①でexecする。

ただこれだけです。

よって

Dockerfile

ENTRYPOINT[ \
  "prehook", "ruby -v", "--", \
  "prehook", "bundle install", "--" ]

Dockerfile

ENTRYPOINT[ "./entrypoint.rb" ]

entrypoint.rb

#! /usr/bin/env ruby

system("ruby -v")
system("bundle install")

exec *ARGV

と別ファイルに切り出せます。

もちろんrubyじゃなくshellでもいいです。

Multi stage build

これだけなら話は早いですが、entrykitを使うからには、おそらくprehook以外のentrykitコマンドと組み合わせたいという使い方が多いと思います。

そんなときの対処方法としてMulti stage buildがおすすめです。

FROM golang:1.15 AS entrykit
RUN go get -v -ldflags "-s -w" github.com/progrium/entrykit/cmd

とすると、Docker環境内でdownloadとbuildが始まり、/go/bin/cmdという実行ファイルが生成されます。これがentrykitの実体です。 cmdじゃなくentrykitという名前でbuildする方法がいまいち分からなかったので誰か教えて下さい……。-oはgo getでは使えないらしい。

ともかくこれで、M1環境でしかもgolang version 1.15でbuildしたentrykitのbinaryが手に入ります。簡単。

次にentrykitを使う場所で、entrykitの実体だけCOPYしてきます。

Dockerfile

COPY --from=entrykit /go/bin/cmd entrykit
RUN entrykit --symlink

これで各種コマンドが生成されます。symlinkはCOPYできないのでCOPY後に--symlinkするようにしましょう。 また、使うコマンドが1つだけなら、

COPY --from=entrykit /go/bin/cmd render

だけでもいいです。お好みで。

Cross buildしてbinaryをプロジェクトリポジトリに置いとく

手元でCross buildして複数環境用にbuildしておき、生成されたbinaryが使われるようにuname -mとかで切り替える。。。

面倒そうな上にMulti stage build以上のメリットはなさそうです。

結論

  • entrykit本当にいるのかどうかよく考えよう。
  • Multi stage build便利。

課題

Multi stage buildの場合、entrykitのファイル配置がおかしいのか、go getでversion指定する方法がよく分からない……。go歴0秒なのでご教授いただけると幸いです。

逆に言うとversion指定しなくてもいいのでメンテナンスレス!

感想

バイナリ配布型のプロダクトの場合、fat gemなどと同じく継続的なreleaseが必要でメンテナ負担が大きいのではないかなと推測します。(作ったこと無いのでなんとも言えないけど)

その点、スクリプト型言語なら再buildなどが必要ないので、 ミニマムに使えるけどメンテナンス負担が大きいバイナリ配布と、 導入は大げさだけどメンテナンス負担が小さいスクリプト配布と使い分けがありそうですね。

とはいえ今回のように都度buildすりゃいいじゃんと言われればまあそうなのかも。

プログラミングElixir / Dave Thomas

 

プログラミング Elixir(第2版)

プログラミング Elixir(第2版)

  • 作者:Thomas,Dave
  • 発売日: 2020/12/01
  • メディア: 単行本
 

 

リンクは第2版ですが、読んだのは第1版です。。。

本を買ってから4年くらい積まれていたのですが、この度第2版が出版されたとのことで、あわてて手元の第1版を読みはじめました。

 

結論からして、読んでないことを後悔しました。

関数型言語は難しそうなイメージで一つも書いたことがなかったのですが、Elixirなら馴染みのRubyっぽい文法で読めるし、これまでよくわかってなかったパターンマッチも、この本を読むことでなんとなく理解できたように思います。

 

パターンマッチはif文のような分岐でもあり、assertionでもあり、変数捕縛でもありと、私の拙い文章能力では意味不明ですが、ともかくパターンマッチによって、これまで自分が見ていた世界を、別の視点から見ることができたような気持ちになりました。

 

自分がこれまでに築き上げてきた考え方を変えることは簡単なことではないですが、本書の丁寧な解説と、読者がプログラミングを楽しめるようにと書かれた著者のお陰で、不思議とこれまでとは別の考え方でプログラムを見ることができた気がしました。

 

タプルとリストの違いには困惑しましたが、タプルは不変で追加や変更等の操作はしないもの。パターンマッチでは `{ :ok, foo } = ...` のように最初にAtomを置く使い方を頻繁にしています。

リストは、数字など同じ型の値の集まりであることが多いようです。

Rubyは大クラス主義なので、どちらもArrayでまかなわれますが、この使い分けはRubyが主要言語の私には新しい発見でした。

 

本文ではif文やfor文など、おなじみの構文はほとんど出てきません。Elixirでは関数とパターンマッチが融合していて、通常はif文を書くところではパターンごとにマッチする同名の関数を書くことで、if文を書かずに済み、かつ名前をつけることができています。名前をつけるほどでもない場合にif文を使うのでしょう。

for文もなくはないのですが、ほとんどはEnum系の関数でなんとかなるようです。

 

Elixir/Erlangのプロセスは、golangのgoroutineのようなもののようです。軽量に生成することができ、平行/並列で動作します。さらにsend/receiveでメッセージをやり取りでき、さらには複数Nodeでも扱うことができOTPという強力なバックグラウンドもあるので、Elixir/Erlangは分散システムを作るのが得意ということなのでしょう。

余談ですが、最近エディタをatomからvscodeに移行しようとしていて、 Elixir用の拡張を探していたのですが、最初に見つけたものがうまく動かず、特にフォーマッターが動いてほしかったのでドツボにはまって自分で自作してしまい、これに時間を使ってしまいました。

後から[ElixirLS](https://github.com/elixir-lsp/vscode-elixir-ls)という拡張なら、フォーマッターを含めオートコンプリートなど全てうまくいくことがわかりました。vscodeのformatter extensionの書き方/読み方がわかったので良しとします。

 

本書によってElixirの魅力に惹かれたので、Phoenixアプリケーションなどもいつか作ってみようと思います。

株式会社MICINで働き始めました

micin.jp

"すべての人が、 納得して生きて、 最期を迎えられる世界を。"

visionにかかげる、MICINで医療系のプロダクトを作っていきます。

MICINって?

私は不勉強ながら、転職ドラフトでオファーがあるまでMICINの名前を知りませんでした(マイシンと読みます)。 しかしながら、実はcuron(クロンと読みます)というオンライン診療サービスで今注目されている企業なのです。

オンライン診療とはその名の通り、病院に行くことなく、オンラインで、【予約→問診→診察→支払い→お薬の受け取り】まで一気通貫でサポートする事ができ、コロナ禍でさらに有用性を発揮し、大きく伸びているサービスなのです。

さらにMICINではオンライン診療だけでなく、データソリューション事業や治験など、医療における多方面への事業を展開しています。(宣伝)

どうしてMICINに?

医療×Techがやりたいなと思って、転職ドラフトをやってみて声をかけられたのがきっかけです。

選考を始めたときは「ちょっと話聞いてみようかな」ぐらいの気持ちでしたが、カジュアル面談や面接で自分の本気の本音をぶつけても、お互いにうまく響いたようで、最終的に「ここで働きたいな」と思えるような医療に対する情熱を感じ、JOINしました。

医療系の中でも、患者寄りの思想である事や、データを活用して医療を良くしていこうという部分が私の経験にもうまくマッチしたように思います。

どうして医療×Tech?

医療がやりたくなった話をしだすと、自分でも想いが溢れすぎて*1もはや自分の文章能力では表現不能と悟ったのではしょりますが、個人的な体験から、誰も見捨てず手を差し伸べるという医療のかっこよさに惹かれ、責任感、親として、使命感、年齢、人生観、その他様々なものが混ざり合い、自分も医療のために働きたいと思い至りました。

そして、私がこれまで磨いてきた技術力と、医療へのモチベーションを掛け合わせれば、自分の力を最大限発揮できると思いました。

どういう人がいるの?

私はしがないWeb系のプログラマーでしたが、社員の皆様の出身は様々で、コンサル、医師、博士、薬剤師、科学者、製薬、MRなどなど、ほんとにすごい経歴の方が集まっています。

そして全員が、医療を良くするにはどうすればいいか、理想面でもビジネス面でも本気で考えています。

こんなに面白い人達が集まって、これからどんな事が起こるんだろうと今からワクワクしています。

心を燃やせ

"俺は俺の責務を全うする!!"

We Are Hiring!

というわけで医療をより良くしていくためにがんばります。

私も医療やってみたいという方は、ぜひご応募ください。

hrmos.co

*1:5000字くらい書いたり消したりした

アドラー流子育てベーシックブック / キャサリン J. ボルス

アドラー流子育てベーシックブック

アドラー流子育てベーシックブック

積読消化習慣ということで、どんどん読んでいきたいと思います。

この本は、Twitterで見かけて購入しました。知り合いがオススメしている本は積極的に読んでいきたい。

子育て本はいくつか読んだことがありますが、本書は理論派というよりは実戦派という感じで、実際にイメージしやすい短いエピソードが沢山載っていました。

セルフケアの重要性を説いている子育て本は初めて読んだので、そこが印象的でした。

子供にイライラしだしたら、セルフケアが足りてない証拠と思えば落ち着きやすいし、イライラしだしているパートナーにも今ケアが足りてないのかもという視点も持つことができました。

この本を読んで、今まで以上に子供が今どういう気持でいるのか、深く気持ちをシンクロさせて考えるようになりました。

そして、今いっぱいいっぱいになってるのかな?とか、主導権をあげれてなかったかな?とかいろいろ打てる手が広がったように思います。


しいて言うなら、広く浅く、8割の子に当てはまればいいぐらいのチップスが多く、根拠も学問ではなく著者の経験からくるところが大きいのが、読者を選びそうです。 また、アメリカ特有の文化もベースにあり、そのまま日本の文化には転用しにくいだろうというエピソードも多数あるので、その辺は気にせず読み飛ばしていました。

最高の一冊に出会った!という感じではないけど、読まないよりは読んだほうが経験が積めて手札が増える。という感じでした。

年内いっぱいでRepro株式会社を退職します

次は決まってます。

はじめに

前回の自分の退職エントリーを読んでみたのですが、何が言いたいのかさっぱりでビックリしました。

最終出社日です - スペクトラム

さて、そんな話は置いといて。

おもいで

ちょうど4年間、Repro株式会社でお世話になりました。 4年間、本当にいろんなことがありました。 正直、自分でも「あれ?Repro辞めるの?待って、マジで?あんな良い所を?なんで???」という気持ちがよく現れて混乱しています。 引っ越しすると決めたのは自分なのに、いざ今くつろいでいる部屋とお別れとなると思うと急に寂しくなるアレです。

会社には本当にお世話になりました。入社時から週4のリモートワークも認めてもらっていてずっと続けていました。(コロナ禍で2020年2月中旬くらいからは一度も出社できていません) 報酬も高く、面白い仕事がどんどん舞い込んできて、大変優秀な方々と一緒にお仕事しながらエンジニアとして成長でき、かつ超過労働もほとんどなく家族の時間も充分持てました。

担当は主にバックエンド側の機能開発が多く、Ruby on Railsな環境が多かったです。

初期はメッセージ機能といって、お客様のアプリを起動するとポップアップが出てくるやつのサーバー側での効率化や、A/Bテスト機能の追加、webへの進出などに参加させていただきました。 効率化についての知見をまとめた記事は、今でもこのブログのトップヒットになっています。(いうても微々たるものですが……。)

Redisで1000万件のデータを圧縮しつつ定期的に洗い替えする - スペクトラム

中期にやったのは、FirebaseでいうRemoteConfigみたいな機能の実装です。私は、要望とサービスの根本的な思想とをすり合わせて、技術的な仕様を決めていきました。メンバーもすごく優秀で、全員の力がフルに発揮されていました。よくあれだけのことを期間内に出来たなあ。これまでで最高のチームでした。

https://docs.repro.io/ja/dashboard/campaign/ux-optimizer.html

「いま***人がこのページを見ています」機能も楽しかったです。実際のデプロイエンジニアリング的なことは他のチームにお願いしたのですが、フロントから集計系のバックエンドまで、まるっとシステムデザインしました。

https://docs.repro.io/ja/dashboard/campaign/social-proof.html

もちろん全て完ぺきにできたわけではありません。未来に遺恨もいくつか残してしまったと思います。その度に悔しい思いをしましたが、この経験を糧にこれからも精進していきたいと思います。

後期は、 JavaScriptにも挑戦させていただきました。結果的にリリースこそ出来ませんでしたが、異なるパラダイムに戸惑いつつも、JSの考え方に触れることができ大変勉強になりました。

後期は実はあんまり働いていません。というのも、半年の育児休業を取らせていただいたからです。「育児休業直後に転職するんかい」という厳しいご指摘には、「おっしゃる通り」と言う他ありません。甘んじて受けいれます。それでも何の障害もなく、すんなりと半年の育児休業を取らせていただいたこと。また、その直後にも関わらず離職をお許しいただいたこと、会社には心から感謝いたします。

後悔があるとすれば、後期は特にコロナもあって、折角ご一緒させていただいた同僚とあまり話せなかったことが悔やまれます。 また、もう少しマーケティングという事業ドメインについて学んでおけばよかったなと思いました。 というのも、次は別の業界ですが、マーケティングの考え方と大変相性が良さそうなのです。 僅かではありますが、これまで経験してきたことを次に生かしていきたいと思います。

もう社内からプロダクトが成長していく様を見られないのかと思うと、寂しく思います。 また、次は知り合いも全くいませんし、自分の選択が本当に正しかったのか、正直不安でいっぱいです。 それでも自分が決めたこと。もちろん並ならぬ想いで悩み抜き、覚悟を持って決めました。決めた自分を信じて、前に進もうと思います。


私は去ってしまうので大変恐縮ですが、Reproは本当に素晴らしい所です。 エンジニアを始め、様々な職種で大募集しておりますので、是非ご応募ください。

https://culture.repro.io/jobs/


さいごに

西新宿のオフィス近くで食べた、もうやんカレー

都庁展望台で食べたランチ。

「この人アイコン見たことある!」って人がどんどん入社してくるワクワク感。

大企業とのミーティングで緊張したこと。

会社の人とスプラチーム組んで、大会に向けて特訓したこと。

OKRやらスクラムやらを導入していくゴタゴタ感。

CTOの圧倒的手腕。

マーガーバーガーの店員さんとの雑談。

すべての経験が、大切な宝物です。

これまで一緒に仕事をさせていただいたすべての方々に感謝します。これまで本当にありがとうございました。 特に id:joker1007 さんには特別感謝を述べたいと思います。素敵な会社に誘っていただいてありがとうございました。

Webで使えるmrubyシステムプログラミング入門 / 近藤宇智朗

久しぶりの読書感想です。どうやら読書感想はブクログとかも含めて4年ぶりぐらいっぽくて、ここ数年の読書しなさが表れています。

本書はmrubyとシステムプログラミングの発展に大きく貢献する良書であると確信します。

本書ではmrubyを利用していますが、そもそものLinux環境でのエンジニアリングについての基礎知識が多く解説されています。mrubyについて学びたい人にとってもシステムプログラミングは良い題材ですし、システムプログラミングを利用したい人にとってもmrubyが助けになるかもしれません。 特筆すべきは丁寧さです。本書の謝辞にもある通り、ハンズオンのための資料を下地にしているため、まるで筆者が隣についていてくれているかのような錯覚を覚えます。本当に一歩一歩丁寧に解説されているため、mrubyやシステムプログラミングに障壁を感じている方でも、安心して一歩づつ学んでいくことが出来るように配慮されています。私は独学でシステムプログラミングを学びましたが、本書によって知識の解像度がグッと上がりました。

mrubyと私

さて、私はかつてmrubyの開発に参加していたことがあります。内容は小さい重箱の隅をつつくようなものばかりで、数だけは無駄に自身があります。 ここ数年はその情熱のほとんどを家族とスプラトゥーン2に費やしたため、しばらくmrubyからは足が遠のき、せいぜい自身が作ったライブラリのメンテナンスを続けていたぐらいでした。

システムプログラミングと私

私がシステムプログラミングに興味を持ったきっかけは、まさにmrubyからだったのです。mrubyを触ってみて、当時大部分の機能がなかったので早い者勝ちとばかりにksss/mruby-signalksss/mruby-file-statを作り始めました。作ってしまったからには中途半端なことはできないと、Linuxプログラミングインタフェースを読みながらライブラリーを作っていたのを記憶しています。今思うとシステムプログラミング初心者があたかも標準であるかのようなライブラリーを作るのは、周りから見たら大変おこがましかったでしょう。無知ゆえの突っ走りです。そんな突っ走りの甲斐あってか、Linuxプログラミングインタフェースを読み終えた時、プログラマーとして一皮剥けたなと思ったことを覚えています。

著者と私

私が著者のudzuraさんに初めて出会ったのは、故spicelife社時代に著者がオフィスにちらっと遊びに来てくれたときのことでした。私は著者のことは知っていましたが、著者にとっては無名の私のことなぞ知る由もないだろうと、同僚と著者が楽しく談笑しているのを横で眺めていた事を覚えています。 その後は、仙台で行われたRubyKaigi2018で行われた How happy they became with H2O/mruby, and the future of HTTP - RubyKaigi 2018 というセッションの後でも出会いました。セッションの話者@i110さんも著者も私はフォローしていたので、これは顔を覚えてもらいつつスプラトゥーンの話をするチャンスと思っていたら、@i110さんと著者とで真面目なmruby談義が始まったので、ふざけようとしていた自分を猛省し身を引いた次第です。 その後、すごくたまたま著者と4リグマをご一緒させてももらったことがあります。もちろんスプラの話しかしていません。

そんなある日、DMで突然著者から連絡が来ました。「ksss/mruby-file-statを本の中で名前を出してもよいか?」というものでした。私は快諾して、この本の発売をまだかまだかと待ちわびていました。

ようやく本の感想に入るわけですけども

mrubyといえば「組み込み向け」と謳われていますが、では「組み込み」とは何なのか。本書では、組み込みとは、ハードウェア組み込みと、アプリケーション組み込みとで大別されると書かれており、私の中のぼんやりとした理解がくっきり鮮明になりました。本書では特にアプリケーション組み込みについて書かれています。mrubyと聞いてハードウェア組み込みをイメージする方も多いと思われるので、本書タイトルの「Webで使える」にアプリケーション組み込みの本であってハードウェア組み込みの本ではないということを表しているようにも思えます。

"CRubyを書くことができる人は、ほとんど学習なしでmrubyを書き始めることができると考えられます"

誰にも伝わらないとは思いますが、私は本書のこの記述にひどく感銘を受けました。なぜなら、こう言われることこそが、私がmrubyで活動していた原動力だったからです。重箱の隅をつつくようなPRをmrubyや周辺ライブラリーに送らせていただいたものの多くは、このCRubyとの互換性を意識したものでした。「CRubyとmrubyは同じように書けば同じように動く。なんならドキュメントはCRubyを参照すればいい。」こういう世界を目指していたので、もちろん私が行った活動なんて微々たるものですけども、こう言ってもらえれるようにmrubyがなって嬉しい気持ちでいっぱいです。

解説の丁寧さ

本書のウリはこの解説の丁寧さにあると私は考えます。例えば、mrubyをbuildするだけのステップであっても、build中に何が起こっているのか、何が実行されて何が生成されて何に使われるのかまで丁寧に解説されています。私なら「rakeしたらbuildできますね」ぐらいで終わってしまうところを数ページ使って、このログはmgemをダウンロードしていて、このログはbuildしていて、このログはアーカイブを作成していて……と細かく解説しています。そしてこのbuild工程は見かけは地味ですがmrubyを理解する上で大変重要になってくる部分なのです。 このように、本当に大切なことを飛ばさず丁寧に一歩一歩読者の隣に立って解説してくれるのが、本書最大の魅力です。 また、ワザとバグを仕込んで、このバグを修正していく過程で知識を学んでいくスタイルも見られます。この方が知識は小出しで覚えられるし、なにより実際にコードを書きながら知識を得ていくステップに即しており現実的です。

「なぜ」の深堀り

本書のもう一つの魅力は「なぜmrubyなのか」「なぜシステムプログラミングなのか」といった「なぜ」にもしっかりと解説が入っている点です。この「なぜ」に答えがあるので、学習する上で重要な納得感が補われており、学習効率を高めています。ここまでしっかりケアしているのは、著者の豊富な経験のなせる技でしょう。 勝手ながら著者について調べさせていただいたところ、パーフェクトRubyとパーフェクトRuby on Railsの著者の内の一人でもありますし、 「GMOペパボは、憧れの会社だったんです」近藤宇智朗(GMOペパボ株式会社)~Forkwellエンジニア成分研究所 - Forkwell Press によると研修の経験も豊富でいらっしゃいます。

さらに、「なぜ」だけでなく「もし」にもケアが入っています。「もしここがうまく行かなかったら、これが原因かもしれないので調べてみてください」のような記述も多数みられ、著者の学ぼうとする人への配慮がみられて素敵です。

ksss/mruby-file-stat

本書ではCRubyのFile::Statclassを実装していく過程をハンズオンで学べる章がありますが、File::Statclassの先行事例としてksss/mruby-file-statを紹介いただいています(アピール)。本プロダクトのGitHubのTraficページによりますと、一日に100〜200回cloneされているので、私が作ったものにしては過ぎたプロダクトとなっております。 本書ではmtimeにusecまで対応している記述があり、「そういえばksss/mruby-file-statはどうしてたっけな?」と思って見てみるとusecに対応しておらず、秒単位までしか取得できていないことに気がつきました。その後、あわててusec対応を済ませました。本書のおかげでksss/mruby-file-statもクオリティが上がり、早速mruby界隈への影響を与えていると言っていいでしょう。本当にありがとうございます。

レビュー

本当に細かなところですが、僭越ながら若干の指摘をさせていただきます。もちろん深い理由があったり、話を簡単にするためにわざと現在のように記述しているのかもしれませんが御容赦ください。

  • __main__ methodを呼ぶ仕様が、mrubyの仕様なのかmruby-templateの仕様なのかが分かりにくかったです。
  • mruby-dir-globは一応あります。
  • File.open(...).readより、File.read(...)の方がfd的に良いのでは。
  • Apacheの問題なので難しいところですが、Requestオブジェクトにap_set_content_typeするとResponseのcontent_typeが変わるので、Requestの話なんだかResponseの話なんだかで混乱しました。

読んだだけじゃ、まだ半分

本書はハンズオン形式になっています。つまりこの本は、実際に手を動かして自分の経験として身につけることで、本の真の知識が読者の血肉として身につくようになっています。 私もまだ一通り読んだだけなので、実際に手を動かしながら本書の内容を学んでいこうと思います。

不安はありません。本書には常に著者が隣に立って教えてくれるのですから。