はじめに:Rubyは死んだらしい。便利だけどな~
ここ一年で技術的な情報を意識するようになったからか、言語マウントが気になるようになりました。Rubyは死んだ、Javaはオワコン、Goは70年代に立ち往生した言語だ、Cは化石だ。
こういった話題を見る度にずっとモヤモヤしてしまいます。どの言語も一長一短あるんだから、0か1かで語らずいいとこどりで活用すればいいのにね。
今回はRubyが叩かれていたので、擁護してみました。
いいところの前に
私のRuby歴
業務で2年程使っていました。Ruby On Railsは触ったことがなく、主にcgiやmruby、テストスクリプトとして利用していました。
それ以外の言語として一番長いのはC。加えてC++、Python、Java、趣味でGoに触ります。
また、Linux開発メインなのでbash(shell script)もよく使います。
備考
※本記事はRubyがNo.1だ!という記事でもありません。当然Rubyのいいところは他にも当てはまる言語が多々あるところだと思います。
他でも出来る=こんなに沢山便利な言語があるってことですよね。いい世の中だ。
※有用なコメントを沢山いただいているので、コメント欄も見ると幸せになれるかもしれません。
※話題に出ない言語は単に投稿主が詳しく知らないだけだと思うので、気軽に読んでいただければと。
Rubyのいいとこ その1. すぐ動かせる
こちらRubyだけじゃなくスクリプト言語全般の特徴ですが、すぐ動かせるのって強いですよね。普段の作業と相性がいい。
通常はbashを使いますが、bashで書くには面倒だけど、サクっとスクリプト化したい作業って結構よくあるんですよね。
例えばこんなのとか
- 設定ファイルをパースした上で、設定値を使ってログを検索する
- HTTPリクエストを投げて、その結果をパースする。
めっちゃ便利なjson形式の設定ファイル、これだけで読み込めるのって凄くないですか!?
require 'json'
str = JSON.load(IO.read("file name"))
※いただいたコメントをコードに反映済み
こういった作業をやる時は、「bashでスクリプト化、はちょっとめんどいな。じゃあrubyかpythonで書こう」ってなります。
スクリプトで使う時は、個人的に1. bash, 2.ruby, 3.pythonなんですが、rubyを上位にしてる理由の一つとして余計なキャッシュファイルが出来ないという点もあります。
本格的なプログラムを組むならpythonのようにキャッシュを作るといいと思いますが、ちょっと使う分にはまっさらな状態で動いてくれるのが嬉しいです。
Rubyのいいとこ その2. RubyGemsが充実
gem install
だけで有用なライブラリがダウンロードできる。何て便利なんだろう!
最近の言語・技術には必ずついてきますよね。pythonもgoもNode.jsにもパッケージ管理ツールはありますが。
Rubyの代名詞のように扱われているRailsも、RubyGemsのパッケージですもんね。
他の言語と比較したことはないですが、使いたいなと思ったライブラリは大抵RubyGemsにある印象です。
(私が馴染み深いライブラリはソースコードを落としてきてコンパイル && リンクでしたが、どんどん便利になっていきますね。)
Rubyのいいとこ その3. 動的型付け
動的型付け、一長一短ありますがちゃんと設計して使えば扱いやすいんですよね。ズボラな定義でも動かせるし、型の拡張が速い。
型で制御できる方が品質が担保される点はいいと思いますが、そこはテストコードや設計で補うことも出来るはず。
なので、動的型付け=悪とせずに、使い方次第でいいところって沢山あるよね!って気がしています。
例えば組込装置のシミュレーターを設計開発した際、環境依存でエンコーダーを差し替える必要があったためこんな感じに設計しました。
利用者はEncoderクラスのencodeを実行。エンコーダーの実体はEncoderManagerで隠ぺいされています。
これですっきりいけそうでしたが、エンコーダーによってはsettingの内容を微調整する必要あり。そんな微調整の際には設定をドーンと流し込める動的型付けのrubyが相性良かったです。
class Encoder
def encode(srcfile, distfile, setting)
#エンコード自体は他のクラスに丸投げ
EncoderManager.get_encoder(srcfile, distfile, setting).encode(srcfile, distfile)
end
end
#エンコーダーは戦略家EncoderManagerが状況に合わせて動的に選択
class EncoderManager
def get_encoder(srcfile, distfile, setting)
case gettype(srcfile, distfile, setting)
when typeA
return EncoderAppA.new(setting)
when typeB
return EncoderAppB.new(setting)
else
return EncoderDefault.new(setting)
end
end
def gettype(srcfile, distfile, setting)
#入力にあったタイプを選択する。
end
end
※いただいたコメントをコードに反映済み
でも、動的型付けのRubyじゃインターフェースのような概念が学べないじゃないか!⇒ほんとに?
また、「Railsは終わった」と言われる理由でインターフェースが学べないと書かれていましたが、それも使い方次第だと思います。
例えば先ほどのエンコーダーの話、以下のようなインターフェースクラスとして用意して、このメソッド構造で各々担当が内部実装する形を取れば、インターフェースの考え方が活かせます。
class EncoderIF
def initialize(setting)
end
def encode(srcfile, distfile, setting)
#FFmpeg等、エンコーダーに合わせた処理を実装する。
raise NotImplementedError.new("#{self.class}##{__method__} が実装されていません")
end
end
言語でサポートされていようがなかろうが、便利な考え方があるなら取り入れて使えばいいし、それで言語を変えた方が効率がいいことがあるなら新しい言語を使えばいい。
ただそれだけのことだと思います。
※いただいたコメントをコードに反映済み
Rubyのいいとこ その4. mrubyで組込分野でも利用可能
私が初めてrubyを触ったきっかけは、h2oというhttpサーバーでした。
組込なので無尽蔵にじゃぶじゃぶメモリは使えない、セキュリティも速度も気にしたいのでOSSのHTTPサーバーから選定したい。かといって毎回Cでガリガリプラグインコードを書くのもコストがかかる。
そこで注目されたのがmrubyが扱えるh2oでした。URLのハンドリングはconfファイルだけで出来て、cgiライクにrubyコードを書けばリクエストが捌ける。
速度が必要な処理があるならmrbgemsという仕組みでmruby機能を拡張することも出来ます。
規模が大きくて燃え上がってましたが、開発自体は割と楽しかった覚えがあります。
言語間の連携が取れると、お互いのいいとこどりが出来ていいですね!
Rubyのいいとこ その5. メタプログラミング
※2019/03/10 追記
コメントいただいたメタプログラミング、ググってみましたが自由度が高いですね!
私がよく使っていた便利機能もあったのでここではそちらを紹介。
状態に合わせたメソッドが大量にあると、switch/caseを書かずにメソッドを切り替えたいことが多々あります。例えばインターフェースクラスの差し替えで補ったり、C言語なら関数ポインタを差し替えたり。
これがRubyだとメソッド名を文字列で指定して実行可能なんですよね。これがかなり快適だったりします。
def method1()
puts("method1")
end
def method2()
puts("method2")
end
send("method1")
send("method2")
上の機能自体はPythonにもあるので唯一無二ってわけではないですが、他にも色々なことが出来る模様です。これは上手に扱えると強いかもしれませんね!
Rubyでメタプログラミング
Rubyでメタプログラミングことはじめ
メタプログラミングRuby第2版:4章:ブロック
最後に: これらはRubyだけに限った話じゃない。言語の優劣・流行り廃りよりもどう活用するかなのでは?
言語それぞれに特徴があって要件に対する優劣はまああって、製品やプロジェクトとの相性があると思います。
言語もツールの一つみたいなもんだと思うので、RubyでもGoでもJavaでもCOBOLでも、その現場に合うものを活用していけばいいのではないかと思います。
この言語をやっていてはエンジニアとしての力が付かない!なんてものはそうそうないと思うので、流行り廃りや言語に踊らされず、どう便利に扱うか考えてみるのはいかがでしょうか?
以上、古代言語と言われるC言語エンジニアがお送りしました。