はじめに
この本について
第1章 Opal入門
第2章 Opal応用編
第3章 実践Opal
第4章 Opalの活用事例
あとがき
先日、RubyKaigi2017というカンファレンスが広島で行なわれました。
表紙の写真はRubyKaigiのあとに訪ずれた、東広島にある西条という街で撮った一枚です。西条は酒蔵の街でいくつもの酒蔵が点在していて、写真にあるような古い煙突や蔵がいまでも残されていてノスタルジックな景観と『酒都』広島のお酒が楽しめるとても素敵な街でした。
さて、RubyKaigiの話です。私はRubyKaigi2017で、「dRuby on Browser」というトークをしました。dRubyはRubyの分散オブジェクトのライブラリーでRubyの動的な特性を活かしてインタフェースの記述を必要としないというとてもすばらしい特徴を持っています。私はdRubyはほんとうにすばらしいと思うので、最近自分がはまっているOpalにいい感じに応用できないかなと思い、Opalでブラウザーで動くdRubyの実装を作りました。
実はRubyKaigiでは去年と一昨年にもトークしていて、いずれもOpalの話題をお話しました。それぞれ「Writing web application in Ruby」、「Isomorphic web programming in Ruby」というタイトルです。いずれも主に私自身で作ったgem(ライブラリー)を紹介したものです。これらのライブラリーについては3章「実践Opal」でこの本のなかでも紹介します。
私がRubyKaigiでトークするようになったのは、当時同僚だったRubyKaigiのチーフオーガナイザーの@amatsudaさんから女性の登壇者が少ないので登壇してほしいと言われたことが始まりでした。(念のため書いておきますが、それはシード枠があった訳ではなく正規の枠でCFPを出してほしいという意味でした。)
何か話をしてほしいと言われても、RubyKaigiで話すネタなど当然なかったわけです(特に当時は転職しばかりでRubyistになって1年くらいだったのです)。またOpalは触ったことすらなくて名前くらいは知っていたという状況でしたが、何かネタを作らなければならないということで当時ちょうどReactがブームになっていたのでVirtual DOMの実装をOpalで作りはじめました。RubyKaigiで発表するためというモチベーションで始めた開発でした。(Kaigi駆動開発なんて呼んでいます。)
そのときは趣味のプログラムを書くためにOpalを使うという話をしていました。あれから3年、RubyKaigiではお馴染のOpalトークということで安定のポジションを得ることができました。そろそろ趣味のプログラムではなく、実用的なツールとしてOpalがつかわれると良いなと思うようになってきました。
しかし3年間の活動の甲斐もなく、Opal自体はいまだにマイナーな存在のままです。
去年くらいから少しづつですが、Opalを使ってもらえるようにする活動を開始しました。そのひとつとしてQiitaのアドベントカレンダーにOpalの記事を書きました。もっと沢山のひとに記事を寄稿してもらえるといいなって思ったのですが、実際には記事を書いたのは私と@yharaさんだけでした。このこと自体はOpalの現状をまとめる良い機会だったなと思います。
そういうわけでアドベントカレンダーに大量に書いた記事がありますので、技術書典3の開催を機に書籍にまとめようということで書いたのが本書です。
内容はもちろんアドベントカレンダーで書いたものの他にも大幅に加筆してあります。3年間のKaigi駆動開発で蓄積されたノウハウと成果を集大成としてこの本に込めました。お楽しみにいただいて、できればOpalを実際に使ってもらえるようになったらうれしいなと思います。
この本の対象読者はRubyに限らずプログラミングを嗜むみなさんです。ただし、Webに関する技術的なバックボーンはあったほうが良いでしょう。つまり想定読者はWebプログラマーということになります。(あまり知らなくても深くつっこんだ話題はないので安心してください。)
また、Rubyに関してはコマンドなどの扱いは注意深く書いたつもりですが、Rubyそのものの文法や標準ライブラリーについては説明を省いています。その辺はリファレンスマニュアルなり他のもので補ってください。
なによりも、Webアプリケーションをつくりたいとか、Opalってなんだろう?つかってみたいとか、そういった興味、好奇心が必要でしょう。
この本の構成は以下のようになっています。
1章「Opal入門」
はじめてOpalを触るひとに向けた入門です。インストールからWebアプリケーション開発をはじめる準備までを扱っています。
2章「Opal応用編」
本格的なWebアプリケーションの開発のまえにOpalからJavaScriptのAPIの呼び出し方からgemのつくりかたまで学びます。
3章「実践Opal」
実際にWebアプリケーション開発を行います。作るのはTODOリストのようなものでとても実用的なものではありませんが、OpalをつかったWebアプリケーション開発の基礎を学びます。
4章「Opalの活用事例」
@yharaさんが寄稿してくれた、「ICFPC ビジュアライザ」と筆者が作ったプレゼンテーションツール「Gibier」を紹介します。
本章では、Opalをはじめて触るひとでもOpalでWebアプリケーションを作ることができるようになるためのチュートリアルです。Opalとは何なのか?Opalのインストール方法、Webアプケーション開発のはじめ方を知ることができます。
それではみなさんOpalでWebアプケーション開発を始めましょう!!
OpalはRubyのソースコードからJavaScriptのソースコードへの変換を行うソースコードコンパイラ(トランスパイラという呼びかたもあります)です。
Rubyというのは、まつもとゆきひろさんが作ったオブジェクト指向のプログラミング言語です。今では有名になったのでみなさん御存じですよね?
JavaScriptももはや説明の必要はあまりないと思いますが、主にWebブラウザーで動くスクリプト言語です。
つまりOpalをつかうとRubyで書いたプログラムをWebブラウザーで実行することができるということです。
Rubyでソースコードを書けると言っても、もちろんMRI(いわゆるCRuby)と厳密に同じではありません。特に標準ライブラリーにいくらかの違いがあります。大きな違いについてだけ以下に列挙します。
プリミティブな型
Opalでは文字列型(String)や数値型(Number)などJavaScriptにあるプリミティブな型についてはRubyの対応するクラスのオブジェクトとしてJavaScript上の値をそのまま対応づけています。このことは、JavaScriptの値における制約をRuby側でもうけることを意味しています。具体的にはString型はイミュータブルですので、upcase!のような破壊的なメソッドを呼びだすことができません。また、Number型は内部的に倍精度の浮動小数点数ですので、Integerとして扱いたいときに問題がでますし、Bignumのような大きな精度の値を表現できません。
Symbolクラス
OpalではSymbolクラスの値もString型の値として扱います。
IOライブラリー
ブラウザー上で実行することを前提としていますので、Rubyの標準ライブラリーにあってOpalの標準ライブラリーとして実現できないものが存在します。その代表的なものがファイルIOなのではないかと思います。OpalはNodeでも実行できますが、Nodeの為にRubyの標準ライブラリーのファイルIOの機能を用意してはいません。NodeはノンブロッキングIOであることが大きな理由なのではないかと思います。
非同期通信
ブラウザーではUIの動きを止めてしまわないように、通信処理は非同期でなければなりません。MRIではそのような制約がありませんが、Opalではブラウザーの制約を受けますのですべて非同期となります。
正規表現
正規表現もJavaScriptの正規表現の処理をつかって行なわれるため、Rubyの正規表現とは違うものになります。なるべく近づけるようにしているようですが差異はあります。
これらは私がこれは大きな違いだなと思う相違の一部です。まだほかにも違いは存在しますが、私はあまり意識せずにプログラミングできましたので心配しなくても大丈夫です。
MRIというのはMatz Implemented Rubyの略で、C言語でつくられたいわゆるCRubyのことです。これは最初にまつもとゆきひろさん(Matz)が実装したRubyということで、そのように呼ばれています。
Rubyにはその他にJavaで実装されたJRubyやRuby自身で実装されたRubiniusなどもあります。もちろん、Opalもその仲間のひとつです。
それではOpalをインストールしてみましょう。と言ってもOpalはRubyのプログラムです。RubyにはgemというRubyのプログラムを簡単にインストールする方法が用意されています。まずはRubyのインストールをしましょう。
Rubyのインストールは環境毎にいろいろありますが、Rubyのバージョンを複数インストールでき、切り換えてつかえるrbenvをお勧めします。ただし、rbenvはWindowsでは使えませんし、私自身もWindowsでは試す環境を持ち合わせていませんのでMacOSやLinuxを前提に話をすすめます。
rbenvをインストールする手段も複数あります。例えばMacOSではhomebrewを使ってインストールすることもできます。そういったOSに標準の方法でインストールするのもよいでしょう。しかしここではもっとも汎用的な方法でインストールします。それは以下のようにgit cloneするだけです。
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
そしてシェルに設定を追加します。以下はbashの場合の設定です。
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
bash以外のシェルでも同様です。書き込む先の設定ファイルが違うことくらいでしょう。
シェルの設定を読み込んで準備ができたら、Rubyをインストールしましょう。この本の執筆時点でRubyの最新バージョンは2.4.2ですのでそれをインストールしてみましょう。
$ rbenv install 2.4.2
それでは最後にOpalをインストールしましょう。Rubyのライブラリーなどのプログラムはgemという形式で作られています。gemをインストールするには下記のようなコマンドを実行します。
$ gem install opal
OpalがインストールできたらOpalを使ってみましょう。まずはREPL1です。Opalにはopal-replというプログラムが付属しています。MRIでいうirbのようなものです。
$ opal-repl
この時に
opal-repl depends on therubyracer gem, which is not currently installed
というエラーが出たら、therubyracerもインストールしてください。
$ gem install therubyracer
opal-replが起動すればインストールは完了です。
コマンドラインからRubyのコマンドをいくつか実行してみましょう。
>> puts "Hello world"
Hello world
=> nil
>> ary = []
=> []
>> ary << 'Hello'
=> ["Hello"]
>> ary << 'world'
=> ["Hello", "world"]
>> ary.join ' '
=> "Hello world"
最後にこのあとでつかうbundlerもインストールしておきましょう。bundlerについては後ほど説明します。
$ bundle install bundler