Rubyでプログラミングの楽しさを知ろう!

よう氏(以下、よう):自己紹介します。「よう」といいます。「youchan」というIDでTwitterGitHubをやっているので、見てください。

Rubyistで、千葉在住です。今活動している千葉のRubyコミュニティがないので、作りたいなと思っています。

あと、大事なことを忘れていました。株式会社レトリバという会社で働いています。最近引っ越して新宿の新宿三井ビルの36階に入居することができました。そういうちょっと高いところで仕事したい人はぜひ応募してください。

(会場笑)

最近の活動についてお話しします。

最近はRubyで機械学習や自然言語処理ができるようにする活動をしています。あとはこういう仲間を増やす活動をしています。「Rubyでできることを増やしたい!」というモチベーションがあります。

その中の1つとして、OpalというRubyからJavaScriptに変換するコンパイラがあります。これはブラウザ上でRubyが使えるという話ですね。あとは自然言語処理ですね。

そのうちのRubyの活動はこんなことをしています。

Opalで動く各種フレームワーク、Isomorphic Programmingって、意味がわからなくてもいいんですが、知りたかったらこの本を買ってください(笑)。

(会場笑)

そういったフレームワークや、RubyKaigiで、2015〜2017年で3回くらい、Opalの話をしています。

あとは、『Pragmatic Opal』という本を書いています。これは最初は同人誌で書いたんですが、インプレスR&Dから商業出版することができました。

Pragmatic Opal Rubyで作るブラウザアプリケーション開発ガイド (技術の泉シリーズ(NextPublishing))

自然言語処理のほうでは、RedChainerという深層学習のフレームワークがあります。これはRubyのやつですね。それの自然言語処理をする部分をやっています。また、『猫と森羅と日本語とRuby』という、日本語の自然言語処理をRubyでやる本を書きました。これは同人誌です。

今年のRubyKaigiでは、このあたりの自然言語処理関係の話をしようと思っています。

あとは、仲間を増やす活動として、こんなことをやっています。

「Rails Girls」ですね。先週、東京でRails Girlsの11回目を開催しました。

あとは「OSS Gate」というものがありまして。これはRubyに限らずなんですが、オープンソースソフトウェアの活動に参加したい人向けのワークショップをやったり、そういう活動をお手伝いしたりしてます。

あとは、『マンガでわかるRuby』という同人誌を書いています。これは「技術書典6」で出展する予定です。ちなみに漫画は私が描いているのではなく、湊川あいさんという方が描いてくれています。なので、これは共著ですね。

他には、こういう場所で登壇をしたり、仲間を増やす活動の一環と言えます。

Rubyの好きなところ

今日は「Rubyでプログラミングの楽しさを知ろう!」という話なんですが、内容としては、私がRubyのどういうところが好きという話をします。

言語としての側面とコミュニティの側面があります。

ところで、スペインではクリスマスに「ポルボロン」と3回唱えると幸せがやってくるというおまじないがあるそうです。

ちなみにこの写真のこのお菓子のことを「ポルボロン」と呼ぶそうです。「ポルボロン」と3回唱えてみましょうということで、こういうプログラムを書いてみました。

(会場笑)

これは実行しなくてもわかりますよね。この中に、私がRubyの好きな部分が詰まっています。

言語として私がRubyの好きなところは、「みんなオブジェクト」ということと「ブロックがとてもよい割り切りをしている」という点です。

みんなオブジェクトである

「みんなオブジェクト」という話です。みんなオブジェクトというのはどういうことかというと、数値や範囲もオブジェクトなんですね。

範囲(がオブジェクトの言語)はいろいろありますが、数値がオブジェクトなのは珍しい言語です。だいたい数値とか、そういったコンピュータで扱いやすいデータ、もともと持っているようなデータは、オブジェクトにはあまりしないで、特別扱いします。

あとはクラスですね。クラスがオブジェクトというのもけっこう珍しいです。クラスって文法的な要素なので、クラスがオブジェクトというのはなかなか珍しい言語です。

数値や範囲もオブジェクトなのでこのようになっています。

これはさっきのやつですね。「3」はオブジェクトなので、「.times」って書くと、Integerのクラスのメソッドが呼ばれます。こちらは範囲ですね。範囲もちゃんとeachというメソッドを持っているので、「3回繰り返す」や「1から3まで数え上げる」みたいなコードが書けるので、すごくわかりやすい、書きやすい言語になります。

次は「クラスもオブジェクト」。これはどういうことかというと、こういう感じです。

先ほどの「3」とかはIntegerクラスです。Integerクラスに「define.method」というメソッドを呼んであげると、メソッドを新たに追加することができます。これを実行してみましょう。

実行するとdegreeというメソッドが追加されます。

例えば、サイン 90°を計算したいといってsin(90)とやると、なんか変な値が返ってくるわけですね。サイン 90°だといくつになるかわかりますかね? これにさっき定義したメソッドを呼び出して渡してあげると、めでたく「1」が返ってきます。

このようにdegreeからradianに変換する、(「Math.sin」というメソッドは、radianを要求するので)「90.degree」って呼ぶとradianが返る、みたいなメソッドを定義しました。

オープンクラスについて

これは「オープンクラス」と呼ばれるテクニックの1つです。

オープンクラスと言われているのは、このように普通のクラスの定義みたいに、classと書いてdefで関数を定義します。いつもみなさんがやっているのと違うのは、ここが「Integer」という既存のクラスになっていることです。このようにクラスにメソッドを上書きすることが簡単にできるのが、Rubyの特徴になっています。

こういうことをすることによって、いろんなことができます。先ほどのdegreeもそうですが、PrimeとかActiveSupport。

これは本当一例なんですが、例えば「2**31-1」が……primeは素数ですね。素数かどうかを求めたい。もちろんこんなメソッドはないので怒られますが、「require “prime”」って呼んであげると、先ほどのやつがうまく動いて、2**31-1が素数だということがわかります。

あるいは、長い数字を素因数分解をしたいときは「.prime_division」って呼ぶと、こうやって2の2乗×3の3乗×5の5乗×7の7乗が導き出されます。

このように「prime」というのをrequireしてあげるだけで、Integerに「.prime?」とか「.prime_division」というメソッドが入るので便利です。

あとはActiveSupportですね。ActiveSupportはRailsにも同梱されているライブラリです。

これも同じようにやるんですが、「今日(3月2日)に47日足すと、いつになるでしょう?」というのをやります。4月18日ということで、今日から47日後に今年のRubyKaigiがあります。

このように、オープンクラスを使うと既存のクラスにいろいろ特徴ができます。これはとてもよいですね。

今やった3.timesとか47.dayとか、dayとかtimeとかって名詞なんですよね。よくオブジェクト指向では「メソッドの名前は動詞にしろ」って言われるんですよ。あるいは「命令形にしろ」って言われるんですね。あくまで原則なんですが、そういうことを言われます。でも、さっきのやつは名詞で定義したりとか。でも、すごくわかりやすいですよね。「今日+47日」とか。

こうやって自由に使っていける、圧倒的な自由がRubyの特徴です。

ブロックが良い割り切りをしている

次に言語的側面で好きなところはブロック。関数型言語が世の中にはあります。例えば、LISPとかScalaとか、Swiftもそうですね。Haskellはピュアな関数型言語と呼ばれていて、ピュアかどうかは彼らにとってとても大事だったりします。

関数型言語としての最低限の要件としては、この「関数が第1級オブジェクトである」ことです。関数が第1級オブジェクトというのは、関数がオブジェクトとして扱えるということです。

それはどういうことかというと、関数の引数に関数を渡すことができるという、ちょっと謎めいた感じになっていますが、具体例を出すとこういう感じですね。JavaScriptで書くならこうなります。

ちょっと実行してみますかね。JavaScriptの便利なところはブラウザで実行できることですよね。あっ、残念。arrayが定義されていないのでダメでした。

arrayは配列だと思ってください。配列にreduceという関数があって、それに関数を渡す。これが関数の定義ですね。

reduceというのは、この関数をarrayの要素ごとに呼んであげて、その中で計算した結果を次のループにまた渡してあげるというやつです。JavaScript……ECMAScriptだとaccみたいな書き方もできますが、それは置いておいて。このように書くことができます。

Rubyで書くとどうなるかというと、先ほどの定義で言うと、Rubyは関数型ではないということになります。Rubyならどうするかというと、ブロックを使います。

arrayにはreduceというメソッドがあって、reduceの後ろにブロックを渡すかたちで書けるわけですね。これはすごく書きやすい、わかりやいです。

ブロックと関数型の違いはいろいろありますが、Rubyのブロックは「引数の最後に1個だけ置くことができる」という制約があります。関数型言語はオブジェクトとして関数を扱えるので、引数のところに与えてもいい、みたいなことになります。

ただし、RubyのブロックはProcというクラスのオブジェクトが実体になっていますので、実は関数型に近いと言えなくもない。ただ、それを呼ぶためには「.call」ってcallというメソッドを呼ばなければいけません。

自由であるが、責任も伴う

このように、圧倒的自由とか言ってたくせに、関数型的な、自由にいくつでも置けるとか、そういった自由さよりも、こういう書きやすさ・読みやすさを優先してるんじゃないの? ってなるわけですよ。

ただし、先ほど言ったとおり、ブロックの正体はProcというオブジェクトで、Procとしてならどこにでも渡してあげることができます。2個でも3個でも渡してあげることができる。

でも、関数の中で渡された関数を呼びたいユースケースって、実はほとんど1個だけで十分ということが多いわけですね。先ほどのreduceもそうですし、例えばコールバック関数を渡したいということもそうですが、ほとんどのユースケースでは1個で十分なわけです。なので、ユースケースによって想定して書きやすい方法を取ることができるのがすごくよいところです。

このようにいろいろな書き方ができるのはよいことだという話もあります。

これは「There’s More Than One Way To Do It」というTMTOWTDIという、「略して何になるんだ?」という省略形なんですけれど(笑)、まぁ、そういう標語があって。

(会場笑)

これはさっきのやつですね。reduceを呼んでいます。これも同じ結果になりますし、arrayにsumというメソッドがあって、それを呼んでも同じ結果になるんですが、このようにいろいろな書き方ができることをよしとしているのがRubyのよいところです。

「誰が書いても同じようになるのがいい」という思想の言語もありますが、Rubyはその逆をいってるわけですね。これは圧倒的な自由です。

ほかにもRubyのいいところを紹介したいんですが、時間に限りがあるので、今日は省略します。

まぁ、自由だと言ってるわけです。Rubyが大好きなところは自由なところです。ただし、自由には責任が伴います。例えばテストをきちんと書くとか、そういった話です。

先ほどのオープンクラスで言うと、オープンクラスって既存のクラスの挙動を変えてしまうこともあるわけです。ただ、そういうこと対して自分で責任を持つ。あまり変なことをしないとか、自由には責任を伴います。Rubyは大人を振る舞いが求められる言語です。