ここ1ヶ月ほど、会社の仕事でRubyを使った開発業務をしている。同時に、プライベートでは、WordPressのテーマ開発やプラグイン開発を進めてもいるため、RubyとPHPとJavaScriptのコーディングを同時並行で行っているというバイリンガルな状況だ。そんな中、仕事の開発業務に費やす時間が多いこともあって、頭や手がRubyのコードに慣れて来ていて、最近オレがコーディングするPHPやJavaScriptでは単純な文法ミスによる「Syntax Error」が増えた。
Rubyに馴れて来ているのか、PHPやJavaScriptでの行末の;(セミコロン)が抜け落ちることが非常に多くなったのだ。最初Ruby始めた時は、この行末に;がない文法に非常に違和感と抵抗感があったものだが、どうやら食わず嫌いに近かったようで、いざその書式に馴れて来ると、逆にPHPやJavaScriptの文法にコーディングコストの高さを感じてうざく思えて来た次第…いやはや何とも節操がないもんだわ(笑)

まだRubyは初めてから1ヶ月弱とほとんど人に語れるようなレベルではないんだが、そんなRuby初心者のオレが、RubyとPHPとJavaScriptのコーディングをやっていて感じたのが、コーディングのし易さではRubyが抜群にイイということだ。ドット・シンタックスでのメソッド・チェーンなど、言語としてはJavaScriptに近いところがあって、PHPよりもJavaScriptが得意なオレの性に合っているというところもある。また、{ ~ }のブロック記法を使わずにdoとかendとかでコーディングしていくと、処理内容が読み取り易い。コメントとか付けなくても、英文読むような感じで処理を読んで行けるというのは、PHPに馴れてたオレにとっては結構カルチャーショックだった。まぁ、ネストが多くなると読みづらくなるのはどんな言語でも一緒なんだがね…。あとは、ループ系の処理が、かなり簡略化して書けるところや、デバッグ用のダンプ処理とかもコーディングコストが非常に少なく済むのも魅力的だ。
例えば、配列変数の文字列を分割して新たに連想配列を作るといった下記のような処理をPHP、JavaScript、Rubyでそれぞれ書いてみると、Rubyの良さが少しは理解してもらえるかも知れない。

PHP

$array = array("postid-1,1,slug-a", "postid-2,2,slug-b", "postid-3,3,slug-a");
$results = array();
foreach ($array as $val) {
  list($id, $number, $slug) = explode(",", $val);
  $results[$slug][intval($number)] = intval(str_replace("postid-", "", $id));
}
var_dump($result);

連想配列$resultsの定義結果は、以下のようになる。

array(2) { 
  ["slug-a"]=> array(2) { 
    [1]=> int(1) 
    [3]=> int(3) 
  } 
  ["slug-b"]=> array(1) { 
    [2]=> int(2) 
  } 
}

まぁ、コーディングコストは少ないんだけど、後述するRubyのコードと比べるとなんか変数部やコマンドのネスト部とかが無骨で読みづらい印象がある。

JavaScript

var array = [ "postid-1,1,slug_a", "postid-2,2,slug_b", "postid-3,3,slug_a" ];
var results = {};
array.forEach(
  function(val) {
    var elms = val.split(",");
    var id = Number(elms[0].replace("postid-", ""));
    var number = Number(elms[1]);
    if (typeof results[elms[2]] != 'undefined') {
         results[elms[2]][number] = id;
    } else {
      eval("var "+elms[2]+" = []; "+elms[2]+"["+number+"] = "+id+";");
      eval("results[elms[2]] = "+elms[2]+";");
    }
  }
);
console.info(results);

JavaScriptには連想配列がないので、オブジェクトとして定義する必要がある。オブジェクトresultsの定義結果は以下のようになる。

Object { 
  slug_a: Array[
    1: 1
    3: 3
  ], 
  slug_b: Array[
    2: 2
  ]
}

evalとか使ってて、このコードはちょっと例としては良くないけど、JavaScriptで擬似的に連想配列作ろうとすると色々と手順と工夫が要る。まぁ、最近はforEach()が使えるようになったので、ループ処理が格段に書きやすくなったのが救いだ。──とは言え、上記のコードはコーディングコストも高いし、読みづらい方だ。

Ruby

array = [ "postid-1,1,slug_a", "postid-2,2,slug_b", "postid-3,3,slug_a" ]
results = {}
array.each { |v| 
  pid, num, slug = v.split(",")
  if !results.has_key?(slug) then
    results[slug] = [pid.gsub(/postid-/, "").to_i => num.to_i]
  else
    results[slug] += [pid.gsub(/postid-/, "").to_i => num.to_i]
  end
}
p results

コーディングコスト的にはPHPよりボリュームがあるように思えるが、変数定義の$とか行末の;とかを記述しなくていいというだけで格段にコードが書きやすい感じを受ける。さらに、$とか;の無骨な記号がないだけでかなりスマートで柔和なコードに見える。実際読み易いと感じるのはオレだけだろうか。
なお、Rubyでは連想配列はハッシュオブジェクトとなり、ハッシュresultsの内容は下記の通りだ。ダンプがpコマンドで書けるのも非常に楽ちんだ。

{
  "slug_a"=>[ {1=>1}, {3=>3} ], 
  "slug_b"=>[ {2=>2} ]
}

改めて比較してみると、Rubyってかなりイイじゃない! とか思ってみたり。
──とは言っても、今の世の中JavaScriptはメインストリーム言語なので捨てられないし、今まで10年以上どっぷりやって来たPHPがオレのメインスキルだし、今のところRubyについては業務以外に接点はなさそうなんで、どこまで本気で食おうか悩んでいるところ…。