技術書典6で、メタプログラミングRuby本を出します


技術書典6に参加します

今回も技術書典にサークル参加します。ブースは「か54」です。

今回の本は、メタプログラミングRuby第2版の内容を追いかけつつ、現実のプログラミングという世界ではどのようにメタプログラミングが利用されているのかを解説する本です。具体的には、Sinatraのコードのなかからメタプログラミングが用いられている箇所をピックアップして、それを教本に従って解説します。

メタプログラミングRuby第2版は、本の中でいくつか現実のコードを出して解説をしている箇所がありますが、いずれも断片的で複数の巨大なコードベースにまたがったものなので、追跡が難しいです。そこで、Sinatraというミニマルなコードベースの中から、強力なメタプログラミングを使っている箇所を取り出し、それがプロダクトに対してどのような意味を持っているのかを考えていきます。

本を書いた環境

こっちが本題です。

前回の技術書典5では、StackEdit+GitBookという環境で執筆を行いました。これはいくつかの要件があったけれど、最終的になんかいろいろうまく行かなくてこうなってしまった、という環境の成れの果てです。詳細は前回のブログを見てください。

今回の環境

いくつかの選択肢がありましたが、今回は最初からRe:VIEWを使って本を書くことに決めました。理由としては、次にあげるいくつかの前回の反省があります。

  • GitBookの成果物は、印刷するのにやや難がある
  • Markdownから望むRe:VIEWの形式に変換するのには、現実的に無理がある
  • というよりも、そもそも文章フォーマットの相互変換に無理がある

Markdownで執筆したものを、望むような形で印刷可能なPDFに変換することは、もはや無理だと悟ったというのが最も大きな理由です。PandocやSphinxも、変換は行ってくれますが結局の所は出力の形式が望んだものになるかどうかは確かではありません。そうなった場合、PandocやSphinxの気持ちを感じながらMarkdownを修正していくということはもはや不可能です。ならば最初から余計な相互変換を持たないRe:VIEWを使うべきだという結論になりました。複数の入力を受けつけ、複数の出力をしてくれるソフトは確かに便利ですが、アンコントローラブルになる箇所が多く、執筆時間が限られているときには選択が難しかったのです。

幸い、Re:VIEWのフォーマットは比較的わかりやすく、リストなどにやや不満はありつつも十分に1日で書けるようになるものでした。そのため、今回は最初からRe:VIEW形式で執筆を行おうと考えました。しかしその一方で、いくつか諦める必要のあるものもありました。

  • ライブプレビュー
  • クラウドエディタ

この二点です。

ライブプレビューに関しては、まあそれはそうという感じしか無く、都度ビルドして確認することしかできません。

クラウドエディタに関しては、まあクラウドエディタでRe:VIEWファイルを書けば良いので特に諦める必要はなかったのですが、EditStackに不満を持っていた私はあれからもっと良いクラウドエディタに出会っていませんでした。良いエディタという意味で言えば、esa.ioはかなり気に入っています。しかし、これはMarkdownに特化しているため、使えませんでした。

しかし、原稿をクラウドエディタで書くことを諦められなかった私は、考えました。結果、Re:VEIWフォーマットとMarkdownはなんとなく似てないこともなかったので、今回はまず概要と草稿をesa.io上で執筆し、そのMarkdownデータを手でRe:VEIWに変換した上で、本を作るための細かな命令などを手元のエディタで行いました。おそらく、技術書を書く上で一番つらいのは、最初の草稿をあげるまでで、そこから先は多少の原稿の修正と、印刷用のマークアップ作業です。なので、その辛い箇所をクラウドエディタでなんとかして、機械的にちかい作業はローカルのエディタで行うように分担したのです。

最終的に、Re:VIEWのファイルはGitで管理してGitHubにプッシュしていたので、GitHub上からクラウドエディタのようなこともできなくはなかったですが、それはやらなかったです。

用意した環境

最終的に用意した環境は次のとおりです

  • esa.ioで草稿執筆
  • vimでRe:VIEWファイルへ書き換え
  • 文章の管理はGitHub
  • Dockerコンテナでビルド

CI等は使っていません。複数人で執筆なら必要だったと思いますが、一人の場合は手元でガンガンビルドするので、特に恩恵はないと思ったからです。

Dockerのイメージには、[vvakame/docker-review: Re:VIEW build container by docker](https://github.com/vvakame/docker-review) を使わせてもらいました。

問題点

草稿までをMarkdown+クラウドエディタで書き、仕上げをRe:VEIWとGitで行うというのはなかなかいい選択肢でした。ただ、問題も一つありました。Re:VIEWは、TeXを中間表現として使っているという点です。

印刷用にマークアップを施し、Re:VEIWで実際にPDFを出力してみて、何か調整したいと思ったときに求められるのは、TeXの知識なのです。残念なことに、私は情報系にしては珍しく大学でTeXを学ぶことがなく、またその後も学ぶつもりがなかったので、TeXのことが全くわかりませんでした。

今回の原稿で具体的に困ったのは、引用したソースコードが行番号付きリストの横幅に収まらなかったケースです。何かしらの方法で改行が必要でしたが、そのために必要だったのはTeXの知識でした。

[【Re:VIEW】表のセル内でURLを折り返しする方法 – himajin315の記録](http://d.hatena.ne.jp/himajin315/20150312/1426146268)

[Re:VIEWで長い文字列を折り返すためにやったこと – patorashのブログ](https://patorash.hatenablog.com/entry/2018/12/12/160511)

これらのページに行き着いても、TeXのことが書いてあって、雰囲気ではわかっても何かエラーが発生したときにそれがどういう原因で出て、どうやって治すのかの当たりをつけるのに困難を極めました。私がうまく行かなかった理由は、設定を記述する順番が間違っていたというものでしたが、そんなもんわかるかという感じです。

とはいえ、Re:VIEWの良い点は、日本語のドキュメントが充実している点と、Twitterで泣き言を言っていると作者の方が拾ってくれたりするところです。

これは本当に助かりました……

次回の執筆環境

今回、Re:VIEWはとてもいいソリューションだと思いました。Markdown2Re:VIEWは諦めて、最初からRe:VIEWで書くことをおすすめします。細かい表現とか、変換時に失われますし。

クラウドエディタに関しては、いくらか思うところがあるので、次回までにはまたいろいろと選定したいと思っています。


カテゴリー: 未分類 | コメント / トラックバック: 0個

Mobb 0.5 and Repp 0.4 out now


このエントリは Mobb/Repp Advent Calendar の二十五日目です

Mobb 0.5.0 out now

🎉

クリスマスなので、超急ぎでリリースしました。Ruby 2.6.0 も出たし。

Mobb 0.5.0では、Advent Calendar で予告していたいくつかの機能がリリースされます。

Mobbのメソッド呼び出しをチェーンする、 chain/trigger シンタックス

BotはBotと会話するべきかどうか?

Mobbの正規表現解釈と、MatchDataの行方

Mobb製のBotになにか処理をさせたが、何も反応を返したくないときはどうするのか

Mobbにおけるマッチのパッシング

これらの機能の新規実装により、 chain/trigger, react_to_bot/include_myself, matched, say_nothing/silent, pass キーワードが新たにMobbに追加されました。

また、次の機能は予告していましたが0.5.0には入りませんでした。

MobbのLogger

Mobbのcronを秒単位で動かす

Mobbのマッチングにどれもヒットしなかった場合のフック

理由としては、実装そのものは概ね出来ているのですが、大きな機能追加が入りきちんとリリース前の検証が出来なかったからです。この機能は、検証が終わり次第リリースします。

Happy Mobb

25日間なんとかACを完走できました、これからもMobbをよろしくおねがいします。

 


カテゴリー: 未分類 | コメント / トラックバック: 0個

Mobb/Repp Advent Calendar のネタが尽きたので、開発してて面倒な話をします


このエントリは、 Mobb/Repp Advent Calendar の二十四日目です

Mobb開発とRepp開発で困る依存性

Mobbの開発には、大きく分けて2つのケースがあります。Mobb単体の機能追加や修正で済む場合と、Repp側にも機能追加や修正が必要な場合です。

Mobb単体で終わる場合にはなにも困ることは無いのですが、Repp側との連携をしなくてはいけない場合は面倒なことが発生します。Repp側の機能追加や修正を、開発中のMobbにどうやって適用するかです。場合によっては、ReppとMobbのコードを行ったり来たりしながら修正を行う場合もあります。

いまのところ、そういったケースではMobb側のGemfileにローカルのReppへの依存を書きます。

一応これでローカルで修正したReppと連携した開発ができるのですが、このGemfileはgitの管理下にあるので、下手になにか追加していると、ブランチのスイッチやリベース時になんか面倒なことになったり、場合によっては間違えてコミットしてしまったりして事故が発生する可能性があります。

Gemfileをgitの管理から外すのが最も良い気がするのですが、こいつはbundlerでgemコマンドを叩いたときに勝手にできるやつだし、なんかどうも消すのに妙な抵抗感があります。

こういう、他のコードと並行して変更する必要がある開発の場合、どうやるのが一番いいんでしょうか?


カテゴリー: 未分類 | コメント / トラックバック: 0個

Mobb/Repp Advent Calendar のネタが尽きたので、対応したいハンドラとか書いときます


このエントリは Mobb/Repp Advent Calendar の二十三日目です。

ネタが切れたので対応したいハンドラとか書いておきます

本当に作るかどうかはわかりませんが

  • Discord
  • LINE
  • IRC
  • ChatWork
  • 他にも何かあれば教えてください

カテゴリー: 未分類 | コメント / トラックバック: 0個

MobbアプリケーションをRack上で起動できるか?


このエントリは Mobb/Repp Advent Calendar の二十二日目です

 

Mobbアプリケーション is Rackアプリケーション?

結論から言うと、動きません。

試しにこんなアプリを書いて起動してみました。

app.rb

config.ru

起動

MobbはRackのアプリケーションとほぼ互換なので、理屈の上では動きそうなものですが、動きませんでした。理由としては、Mobbがサービスからの情報を受け取ったときに処理するfilterやhandle_eventメソッドの中で使われている、process_eventメソッドにありました。

process_event の中身は次のようなメソッドです。

この中で、 @env.body を参照している箇所に問題がありました。Reppと違い、Rackの送ってくるenvオブジェクトには、bodyというメソッドが存在しないからです。

比較のために、Mobbが参考にしているSinatraのprocess_routeメソッドを見てみましょう。

最初に参照しているのが、 @request.path_info というメソッドで、これはどう考えてもHTTPに存在し、チャットボットに存在しない概念です。

残念ながら、MobbをRackで動かすという試みは、このRackとReppの微妙な世界観の違いで頓挫しました。

MobbをRackで動かせるべきか?

答えはNoです。MobbはSinatraを最大限にリスペクトしていますが、Sinatraの世界観とは違うものです。もちろん動かせれば面白いとは思いますが、MobbをRackに対応させる理由は全くありません。


カテゴリー: 未分類 | コメント / トラックバック: 0個