プログラマーの心を揺さぶる:RubyからGoへの衝撃的な言語遍歴


Summary

ふと気づけばGoを書いて3年目──あの日Rubyで感じた『コードが踊るような楽しさ』とは別次元の充足感があることに気づいた。この記事は、あるエンジニアが2つの言語で味わった衝撃的な学びを綴る旅日記みたいなもの Key Points:

  • Rubyの詩的なコードからGoの実用性へ──あるプログラマーの言語遍歴で気づいた「書きやすさ」と「スケーラビリティ」のジレンマ。メモリ使用量がふっと増えるあの瞬間、もうRailsの魔法だけじゃ解決できないかも
  • GILとの戦いやコールバック地獄…大規模開発で露見するRubyの限界。でもGoに移行したら、今度はgemのような豊富なエコシステムが恋しくなる逆転現象。どっちが正解じゃなくて、プロジェクトのフェーズで選ぶものだと思った
  • 言語変えるってコミュニティの空気感まで変わるんだよね。Rubyカンファレンスの温かみからGo勉強会の実務チックな雰囲気へ。OSSへの向き合い方も自然と変わっていくのが面白くて、でもどこか寂しいような
結局どちらが優れているかではなく、それぞれが照らす開発者の原体験こそが重要だと気付かされる物語

十年以上もRubyと付き合ってきた人がいるらしい。どうやら、最初の頃はその言語の美しさだとか、詩みたいな書きやすさ、それに仲間内の活気なんかに惹かれていたみたい。Railsを使えば、ちょっとしたアイデアがあっという間に形になったことも多かったそうだ。Rubyって、人によっては「物語を書く」みたいな感覚でコードを書けると言う人もいるし、確かに慣れれば流れるように思える瞬間もある。

ただ、この辺りから話が少し変わる。規模がそこそこ大きくなったり、複雑さが増していくと…何となくだけど土台が揺らぎ始める印象を受ける人もいるようだ。パフォーマンス面でひっかかりを感じたり、一度に複数の処理をこなすには工夫が必要だったり、エラー内容も時々よく分からなくなる。そのせいか、「もっと強靭なもの」を探したくなるケースもある。

そんな折、Goという言語にふと目を向けてみた人もいる。それはRubyとは全然違う雰囲気で、「エレガント」というより「力強い」「素朴」とでも言うべきか…。実際、その切替以降もう戻っていないという話も耳にする。ただし、「Rubyの美点を捨てた」というよりは、「必要な場面ではスピード感やシンプルさ、それと信頼性重視でGoを選ぶ」という考え方になる場合が多い。

まあ、本当に全部手放すわけじゃなくて、場面ごとの道具選びなのかな、と感じることもしばしば。ちなみにRuby自体への愛着や、その書き味の良さ…それは今でも忘れ難いものとして残ることが多いそうだよ。

最初にRubyと出会った時の衝撃――あれは本当に「人間向け」の設計思想だったんじゃないかなあと振り返る声もちらほらある。「直感的」「会話みたい」と表現されることもしょっちゅう。でも年月が経つにつれて、新しい課題や他言語への関心へ自然と向いてしまう、それくらい移ろいやすい世界なのかもしれないね。


Rubyのコードを書いている時、詩みたいだなと何となく感じたことがある。メソッド呼び出しもブロックも、それぞれに意味があって、楽しい…と言いたくなる瞬間があった。Railsを使うと、数日でそこそこのWebアプリが形になる。設定より習慣重視みたいな考え方だから、細かい所に悩まず機能づくりに集中できる気がした。そういえばRubyのコミュニティって不思議な温度感で、地元の集まりや世界的なイベントまで色々あったような記憶がある。みんなOSS好きだったりして、一緒に楽しくやろうという空気は確かにどこか感じた。

DeviseとかActiveRecordとかRSpec、その辺りのgemには随分頼ってきたけど、本当に色んなツールが揃っていた。開発自体も少し創作活動っぽさを感じることもあったんじゃないかな。

ただ――規模が大きくなるにつれて(具体的には数百万単位? いや数十万超えてからかもしれない)、リアルタイム処理や複雑なデータパイプライン絡むようになって、Ruby特有の制約を意識せざるを得なくなった事例もちらほら見聞きする。GILの影響なのか、本格的なマルチスレッド実装は難航しやすかった気配だし、大量データ扱う案件ではメモリ使用量もいつの間にか増えていた印象だった。

Rails独特のコールバック深い所でエラー追い掛けていると、原因探しに時間ばかり吸われてしまうことも…。ふと思った——この「書きやすさ」が逆に足枷になる場面も出てきてしまうんだろうか、と。
Extended Perspectives Comparison:
言語エラー処理のスタイル設計思想コミュニティの雰囲気デプロイの簡便さ
Ruby放任主義的で、例外が埋もれることが多い。柔軟性があり、凝りすぎた書き方になりやすい。温かく賑やかで他に類を見ない。多くのgem依存関係が発生し、設定が面倒。
Goエラーは値として返し、明確に扱われる。シンプル志向で、高度な機能は少ない。仲間意識はあるものの、Rubyほど賑やかではない。単一バイナリファイルでデプロイが非常に簡単。
比較点1エラー処理: Rubyは静かに失敗する傾向あり; Goは常に目につく。
比較点2
結論両言語にはそれぞれ良さがあり、用途によって使い分けることが重要です。また、新しい道具としてGoを試してみる価値があります。

2. Rubyとの出会いがまるで恋に落ちるような体験だった理由

Goについて、最初にその名前を耳にしたのは、どこかで同僚が「Rubyとは反対方向なんだけど、それが意外といい感じ」とぼそっと言ってたからだった気がする。何となく興味が湧いて資料を眺めてみると、Google発の言語らしく、クラウドとか分散システム辺りに向けて作られているようだった。Rubyは開発者の心地良さ重視っぽい雰囲気があるけど、Goはもう少し現実的な要素――例えば速度や安定性――に寄っている印象。

最初に書いたプログラムは確か簡単なHTTPサーバー。標準ライブラリだけでちょっとしたコードを書いただけなのに、一瞬でサーバーが動き出して驚いたことを思い出す。余計なフレームワークもなくて、本当にGo本体だけで十分だったんだよね。その時点ではGemとか追加パッケージみたいなものも特になくて、不思議なくらいシンプルだった。

構文も何となくあっさりしていて、キーワード数も七十個には到底届かないくらいしかなかったような…。Rubyはいろんな言葉や記法が多くて覚えることも多かったけれど、その点Goはかなり覚えやすかったと思う。ただ、それよりもっと惹かれたのは速度面や並行処理への対応力。Rubyだと処理速度やスレッド絡みで悩むことがよくあったけど、Goではそういう部分で多少ラクになる場面もあったかな、と今でも感じる。

ちなみにパフォーマンスについて話す人も多い。Goの場合コンパイル型なので直接機械語に落ちるわけだけど、それによって体感できるくらい速さや効率につながっている、と語るエンジニアを時々見かけたりする。でも、その効果が一概に全員へ当てはまるかどうか…まあ用途次第という感じなのかもしれない。

Rubyのスクリプトって、どうも処理速度があまり速くない印象が残ることが多い。以前見かけたプロジェクトの話なんだけど、Rubyで書かれていたAPIは、七千とかそれよりちょっと多いリクエスト数をさばこうとすると、CPU負荷が急に上がりやすかった気がする。そのあとGoで同じAPIを作り直したらしいんだけど、今度は十万近くリクエストが来ても余裕そうだったっていう人もいるみたい。同じ機械なのに随分違うなぁ、と感じる瞬間だったとか。もちろん全部のケースでこうとは限らないけれど、大きなデータ処理とか、高頻度アクセスのAPI運用、それからKubernetesみたいな環境でマイクロサービスを動かす時なんかにはGoの性能面の強みが現れる場合もあるようだ。メモリ使用量についても、Rubyと比べて控えめという声を何度か耳にしたことがあるし、ごみ集め(ガーベジコレクション)も遅延対策されている、と言われている。それでインフラコストもちょっと抑えられる場面も出てくる可能性がありそう。ユーザー体験にも少し影響するのかな。

ところで並列処理について触れておくと、RubyはGILっていう仕組みのせいで、本格的な並行実行はやや難しい部分もあったっけ。EventMachineとかSidekiqなんかを使って工夫していた人たちもいるけど、それでも根本的な解決には至っていない感じだったかな…たぶんバンドエイド的という表現になることもある。

4. Go言語との衝撃的な出会いと最初の印象

Goって、まあ最初から並行処理を意識して作られてる感じがする。goroutineとか、名前は聞いたことある人も多いかもしれないけど、実際使ってみると「ああ、こういうものか」と妙に納得する瞬間が来るんだよね。軽いスレッドみたいな動きをしてくれるし、自分で管理しなくていいのが楽だった気がする。ただ、数え切れないくらい同時に走らせても大きな問題になりにくい印象が残ってる。

一度IoT関連のデータ処理をやったことがあって、そのとき他の言語……たとえばRubyなんかだと、大げさに言うと何重にも仕組みを作り込まないとうまく回らなくて。Redisとか使いつつワーカー増やしたり減らしたり、それでも思ったより手間やトラブルが尽きなかった記憶。Goで書き直してみたら、なんというか複雑さがぐっと減ったかな?もちろん個人差はあると思うけど、自分の場合は割と素直にできた。

チャネルっていう通信方法もあって、それでゴルーチン同士で「ちょっとこれお願い」みたいなやり取りもできたりするので、不思議と全体像も追いやすかったような…。結局パフォーマンスもちょっと上向いた気配はあったけど、それ以上に混乱しづらかった点が助かったんじゃないかな、と今振り返れば思う。

正直Rubyだけでは実現しづらかった部分もあったから、人によってはGoの並行性を「便利」と感じる場面もありそう。まあ、「絶対コレ!」という話ではなく、その状況次第で選択肢になるという程度。でも、一度触れてしまうとなかなか忘れ難い感覚なのは確かだと思う。

Rubyのエラー処理って、なんだか放任主義っぽい印象がある。気づいたらログの隅に例外が埋もれてて、静かに失敗してることも珍しくないんじゃないかな。Goの場合は全然雰囲気が違う。エラーは値として返すだけで、例外を投げたりしない。それってつまり、「この先どうする?」と毎回問われる感じで、見逃しを減らす助けにはなると思う。ただ最初は、どの関数呼び出しにも「もしエラーなら……」みたいなチェックが付いてくるから、正直ちょっと面倒だった記憶もある。でも何年か使っていると、その明快さに慣れてきたというか。Rubyではつい端っこを忘れたりして、それが分かるのはユーザーから報告が来てから――そんな経験をした人も少なくない気がする。一方Goだと、エラー部分がほぼ常に目につくし、そのせいでコード全体の堅牢さや見通しやすさにつながりやすい、と感じている人もいるようだ。まあ、おしゃれとかスマートとは言えないんだけど、実用面では悪くない選択肢なのかもしれない。

話をちょっと変えると、Go自体の設計思想ってかなりシンプル志向なんだよね。「これしかできません」と言われたような気になる時もあるくらいで、高度なメタプログラミングとか演算子の自由な書き換えみたいなものは最初から用意されていない。そういう意味では賛否両論っぽくて、人によっては少し物足りなく感じることもありそう。でも、その割り切った作りのおかげで、ごちゃごちゃ考えずに済む場面も多くなる――保守性とか読みやすさ重視なら、この方向性もうまく働いていると言えるんじゃないかな。ただ全部それで十分なのかどうかは、多分状況次第だけど……

6. Goの並行処理が開発者にもたらす革命的な変化

Rubyって、ちょっとした柔軟さがあって面白いんだけど、その分ちょっと凝りすぎた書き方になりやすいんだよね。なんていうか、保守とかデバッグの時に「あれ、これ何してるんだっけ?」みたいな場面が出やすい。Goの場合は、そういう複雑なトリックをあまり許さない雰囲気があるから、チーム作業とか長く動かすプロジェクトでは安心感がある気がする。実際、標準ライブラリもわりと充実していて……例えばJSONをパースしたり、とりあえずHTTPサーバー立てたり暗号関連まで、一通り入ってる印象かな。追加でライブラリ入れなくてもなんとかなっちゃうこと、多かったような?

それに比べてRubyだと、小さいプロジェクトでもやたらと色んなgem(外部のパッケージみたいなもの)を使うことになる印象だったかも。それぞれクセが違うし、保守もちょっと大変だった記憶がぼんやり残ってる。

さて、デプロイの話。前にRubyアプリを本番環境に載せようとするとき、大体PassengerとかPumaとかHerokuみたいなのをどう設定するか悩むこと多かったような…。加えてgem周りの依存関係とか、いつの間にかRuby自体のバージョンにも注意しないといけなくなる。一方でGoはというと、本当に驚くぐらい単純化されている気配。コードを書いてビルドすると、一つだけのバイナリファイルができる。そのままサーバーに持って行けば動くので、「え、それだけ?」みたいな拍子抜け感もあるくらい。全部自己完結型だから、人によっては新鮮に映る場面もありそう…そんな感じかな。

Goのシンプルさって、特にマイクロサービスとかコンテナ環境だと、かなりありがたい存在みたい。前に、とあるプロジェクトでGo製の小さいサービスをいくつもKubernetes上に並べて動かしたことがある人がいたけど、全部一つのバイナリだけで済んだから、デプロイは思ってたよりサクッと終わったらしい。比べてみるとRubyの場合、なんだかんだでgemが合わなくなったりDockerのイメージ調整で半日潰れたり…そんな話も耳にする。だからGoなら運用周りがちょっと楽になるよね、って感想もちらほら。

でもまあ、そのまま何もかも上手くいくわけじゃないっぽい。Ruby独特の美しさというか柔軟さはやっぱり恋しくなる瞬間も出てくるようで。メタプログラミングなんかはRubyのお家芸みたいなところがあって、有名なRSpecとかActiveRecordの書き方なんて本当に表現力豊かな気がする。でもGoにはそういう発想自体あまりなくて、型システムもしっかりしてるから逆に窮屈に感じる人もいるみたい。

あとコミュニティについて言うと、Ruby界隈の雰囲気や温かさは他ではなかなか見当たらないとも。一方でGo側にも仲間意識みたいなのはじわじわ育ってきているものの、それでもまだRubyほど賑やかな空気とは言えないかな…そんな声を聞いた覚えがある。

まあ結局、「どっちにも良さはある」ぐらいで落ち着く話なのかもしれない。

8. Goのシンプルさがチーム開発でもたらす意外なメリット

Goの標準ライブラリ、まあしっかりしていると言われてるけど、Rubyのgemみたいに細かい画像処理とか自然言語解析みたいな分野には、ちょっと手が届きにくい気がする。数え切れないほどあるわけじゃないから。あと、Goってぱっと見シンプルそうだけど、実はゴルーチンやチャネル、それからインターフェースなんかを本当に理解しようとすると、それなりに時間がかかったりする。Rubyみたいな動的言語から来た人だと、とくに最初は戸惑うことも多いんじゃないかな。

小さめのスクリプトや素早く何か試したい時は、自分の場合やっぱりRubyを選ぶことが多い。プロトタイプ作るならRubyで十分だと思う。ただ、本格的なシステムとか大規模になってきたり、高速性とか安定性をちゃんと求められる場面では、不思議とGoの良さがじわじわ効いてくることもある。

もしRuby書いてる人なら、「もう全部Goに乗り換えよう」とまでは全然思わない。でも、スタートアップ的なMVPや社内ツールだったら今まで通りRubyでも困らないし、生産性重視ならなおさら。ただ、アプリケーション自体が成長してきたり、例えば分散システムとかクラウドネイティブ開発、それから高負荷APIみたいな領域で手こずった経験があるなら、一度くらいGoを触ってみても損はしないんじゃないかな。

週末使って小さいAPI書いたりCLIツール作ったり、データ処理系のワーカーを書いてみると、「あれ?」と思うほど速度感やコードの明快さを感じる瞬間があるかもしれない。それで、「これ悪くないな」ぐらいには思える可能性もある。もちろんRuby独特の表現力というか詩的なところは恋しくなる時もありそうだけど、その分、新しい武器という意味でGoは案外役立つこともある気がする。まあ、人によって違うだろうけどね…

GoがRubyを置き換えるとか、そんな話ではなかった気がする。むしろ最近だと、どちらも一緒に使う場面が増えてきたような…。Rubyは、ちょっとした試作だったり、サクッと形を作る時によく登場していて、そこからどうにもパフォーマンスが厳しい部分はGoで補強することになる。まあ…この組み合わせ、世の中でも結構見かけるって聞いたことがある。

思えばRubyからGoへ乗り換えるというより、「優雅さ」を手放す代わりに何か違う力を受け入れる感覚だった。Goのおかげで「シンプル」って案外大事なんだなぁ、と気づかされることも多いし、信頼性とか壊れにくさみたいなものを前より意識するようになった気もする。それでも…見た目はあんまり格好良くないコードになる時もあって。でもまあ、それでちゃんと動けばいいんじゃないかな?ソフトウェアなんて所詮、そのためのものだから。

もしRuby好きな人たちがこれ読んでいるなら、一度くらいはGoを触ってみても悪くないと思う。ただ慣れるまで多少クセも感じるし、人によっては途中で「やっぱ合わない」となるかもしれない。でも個人的には、新しいツールの荒削りなところにも不思議な魅力を見つけたりして…。結局、「力強さ」にもちょっとだけ美しさみたいなのがあるのかな、と感じ始めている自分に気づいたりする。ま、それぞれ試してみて、自分のプロジェクトに合う部分だけ取り入れるくらいの軽いノリでも十分だと思います。ここまで書いて何となくまとまらなくなってきたので、この辺で失礼します。

Reference Articles

ブックマークしてあった、データサイエンスなどの記事約 ...

個人的にはてぶでブックマークしていた記事、2018年5月初旬ごろまでの、AIだったり分析だったりその他のカテゴリの約1年分くらいのリンク集です。

Source: Qiita

卒業研究履修の手引

教員と直接ふれあうことの少ない放送大学において、卒業研究は、指導教員から直接指導を受けることのできる、またと. ない機会です。

Source: 放送大学

相澤 清晴 (Kiyoharu Aizawa)

Expert

Related Discussions

❖ Related Articles