CodeIQ MAGAZINECodeIQ MAGAZINE

「Ruby風味のプログラミング言語」四天王現る!Elixir,Crystal,Opal,Mirahまとめ #ruby

2015.07.22 Category:技術コラム Tag: , , , ,

  • 151
  • このエントリーをはてなブックマークに追加

話題のRuby風の文法を持つ言語、Elixir,Crystal,Opal,Mirahについて、まとめてみました。

各言語の特徴・サンプルコード・関連資料リンクを整理したので、ぜひお役立てください。
by tbpgr

Rubyじゃだめなんですか?

出題者のtbpgr(てぃーびー)です。

最近噂になることが多いRuby風の文法を持つ言語についてまとめました。

Rubyはバージョンを経るたびにパフォーマンスが改善されていますが、一部の高速な言語に比べると見劣りします。

また、パフォーマンス以外にも

  • Rubyの文法は好きだけど型推論がほしい
  • 関数型言語の領域でRubyを利用したい

など、Rubyがカバーしていない領域でRubyの文法を使いたいという需要があります。

そこでRuby風味の言語たちの登場です。

目次

  1. Elixir
  2. Crystal
  3. Opal
  4. Mirah

Elixir

Erlang VM上で動作する関数型言語です。

特徴

  • 関数型言語
  • メタプログラミングしやすい
  • DSLを作成しやすい
  • テスト可能なドキュメントDoctests
    • ElixirではAPIドキュメントにIExの入出力を記載しておくことでテストとして動作する
  • 便利なツールが言語に同梱されている
    • 単体テストフレームワークExUnit
    • REPL IEx
      • RubyではirbやpryでおなじみのREPLとしてIExが提供されている
    • CLIツール mix
      • プロジェクトテンプレートの生成
      • プロジェクトのビルド
      • プログラムの実行
      • テストの実行

サンプルコード

FizzBuzzのプログラムを作成します。
from,toを引数にとり、fromからtoの範囲を
FizzBuzzの出力範囲とします。

defmodule do-endがモジュールの定義です。
関数をdefで定義する点はRubyと同じ。
defpはRubyのprivate defにあたります。

@docの部分はAPIドキュメント用のコメントです。
この部分にiex>+実行コードと次行の実行結果を記述することで、
テスト可能なドキュメントを作成しています。

defmodule Fizzbuzz do
  @doc ~S"""
  FizzBuzz.

  ## Examples

      # only other numbers
      iex> Fizzbuzz.fizzbuzz(1,2)
      [1, 2]

      # only Fizz
      iex> Fizzbuzz.fizzbuzz(3, 3)
      ["Fizz"]
      iex> Fizzbuzz.fizzbuzz(6, 6)
      ["Fizz"]

      # only Buzz
      iex> Fizzbuzz.fizzbuzz(5, 5)
      ["Buzz"]
      iex> Fizzbuzz.fizzbuzz(10, 10)
      ["Buzz"]

      # only FizzBuzz
      iex> Fizzbuzz.fizzbuzz(15, 15)
      ["FizzBuzz"]
      iex> Fizzbuzz.fizzbuzz(30, 30)
      ["FizzBuzz"]

      # mix case
      iex> Fizzbuzz.fizzbuzz(1, 15)
      [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz"]

      # args 'to' not integer
      iex> Fizzbuzz.fizzbuzz("1", 15)
      ** (RuntimeError) invalid argument
          (fizzbuzz) lib/fizzbuzz.ex:37: Fizzbuzz.fizzbuzz/2

      # args 'to' not integer
      iex> Fizzbuzz.fizzbuzz(1, "15")
      ** (RuntimeError) invalid argument
  """
  def fizzbuzz(from, to) when is_integer(from) and is_integer(to) do
    from..to |> Enum.map(&(fizzbuzz/1))
  end

  def fizzbuzz(_from, _to), do: raise "invalid argument"
  defp fizzbuzz(num) when rem(num, 15) == 0, do: "FizzBuzz"
  defp fizzbuzz(num) when rem(num, 5) == 0, do: "Buzz"
  defp fizzbuzz(num) when rem(num, 3) == 0, do: "Fizz"
  defp fizzbuzz(num), do: num
end
  • テストコード

doctestを指定することで、APIドキュメントをテスト対象にすることができます。

defmodule FizzbuzzTest do
  use ExUnit.Case
  doctest Fizzbuzz
end
  • mixtestを実行してみます。APIドキュメントの内容がテストとして実行されます。
$ mix test --trace
Compiled lib/fizzbuzz.ex
Generated fizzbuzz.app

FizzbuzzTest
  * doc at Fizzbuzz.fizzbuzz/2 (4) (4.8ms)
  * doc at Fizzbuzz.fizzbuzz/2 (7) (1.9ms)
  * doc at Fizzbuzz.fizzbuzz/2 (1) (0.1ms)
  * doc at Fizzbuzz.fizzbuzz/2 (2) (0.1ms)
  * doc at Fizzbuzz.fizzbuzz/2 (5) (0.1ms)
  * doc at Fizzbuzz.fizzbuzz/2 (3) (0.1ms)
  * doc at Fizzbuzz.fizzbuzz/2 (6) (0.08ms)


Finished in 0.1 seconds (0.1s on load, 0.01s on tests)
7 tests, 0 failures
  • mixでFizzBuzzを実行してみます
$ mix run -e 'IO.inspect Fizzbuzz.fizzbuzz(1, 30)'
[1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14,
 "FizzBuzz", 16, 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", "Buzz", 26,
 "Fizz", 28, 29, "FizzBuzz"]

補足

すでにElixir言語で実装されたWeb Application Frameworkも存在します。

Phoenix – GitHub

関連資料

目次に戻る

Crystal

Ruby風の文法を持ち、高速に動作する言語です。
「高速な処理が必要。でもRubyで書きたい」という領域での活躍が期待されます。

特徴

  • Ruby風の文法
  • 静的型チェック
  • Crystal内でCのコードを呼び出せる
  • 効率的なnative codeを吐き出す

サンプルコード

配列の初期化時にString型を扱うことを明示している点が特徴的です。

class FizzBuzz
  def fizzbuzz(from, to)
    (from..to).inject(Array(String).new) do |a, e|
      a << case
      when e % 15 == 0 then "FizzBuzz"
      when e % 5 == 0 then "Buzz"
      when e % 3 == 0 then "Fizz"
      else e.to_s
      end
    end
  end
end

pp FizzBuzz.new.fizzbuzz(1, 15)
  • 出力
FizzBuzz.new.fizzbuzz(1, 15) = ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz"]

補足

すでにCrystal言語で実装されたWeb Application Frameworkも存在します。

Amethyst – GitHub

関連資料

目次に戻る

Opal

Rubyで記述したコードをJavaScriptにコンパイルするAltJS言語です。

特徴

  • Rubyの文法でJavaScriptを書ける

サンプルコード

Playgroundで実行され、JavaScriptのコードを生成している様子です

補足

すでにOpalを利用したWeb Application Frameworkも存在します。

Volt Official

関連資料

目次に戻る

Mirah

MirahはJRubyの開発者がJRubyの開発のために作成した言語です。

特徴

  • Ruby風の文法
  • JVMで動作する
  • メタプログラミングとマクロ
  • Javaと同等のパフォーマンス
  • Javaのライブラリを呼び出し可能

サンプルコード

class FizzBuzz
  def fizzbuzz(value:int)
    if value % 15 == 0 then "FizzBuzz"
    elsif value % 5 == 0 then "Buzz"
    elsif value % 3 == 0 then "Fizz"
    else Integer.toString(value)
    end
  end
end

puts FizzBuzz.new.fizzbuzz(1)
puts FizzBuzz.new.fizzbuzz(3)
puts FizzBuzz.new.fizzbuzz(5)
puts FizzBuzz.new.fizzbuzz(15)
# Javaのライブラリを利用
puts System.getProperty("java.specification.version")
  • 出力
1
Fizz
Buzz
FizzBuzz
1.7

関連資料

目次に戻る

現在出題中のRubyに関する問題はこちら!

  • 151
  • このエントリーをはてなブックマークに追加

■この記事を書いた人

avatar

tbpgr

CodeIQでRubyや様々なカテゴリの問題を出題中。 Twitter:@tbpgr Tbpgr Personal Page: http://tbpgr.github.io/

■関連記事

コピペさんプレゼンツ。宝石と蛇を用いたExcel方眼紙スクショペタペタ自動化入門... はじめに 今回は連動問題にもでてくる、湊川あいさんイラスト担当のキャラクター「コピペさん」が事例を紹介してくれます。 香ばしいおっさんであるところの私が書いた文章だと思うと残念な気持ちになるかもしれませんが、湊川さんに女性の視点で協力していただくことで残念さが払拭されていることと思います。 E...
Fix typo駆動でOSSに貢献する。RubyへのFix Typo Pull Requestの実演... システム開発の仕事と切っても切り離せないOSS 昨今の開発において多くの人がOSSの恩恵を受けています。 そして、GitHubの登場により普段利用している「あのソフトウェア」に 貢献することも大きな障壁ではなくなりました。 OSSに対する貢献は強制されるようなものではないものの、 「私にもできる...
佐々木俊尚氏を顧問に、オウンドメディアも開設!家事シェアサービス「Any+Times」は、個人のスキ... 誰かのニーズと誰かのスキルを、Webとリアルで交換 仕事で毎日遅くなるので、掃除や洗濯をする時間が取れない。そんな悩みを持つエンジニアも少なくないのではないだろうか。ハウスクリーニングサービスはいくつもあるが、安心して頼めて、かつ低コストのサービスはそうそうあるものではない。 「私自身が、便利屋...
綺麗なコードと汚いコード。どちらのプログラマと一緒に働きたい?~可読性を意識したプログラム言語はRu... プログラムの可読性について CodeIQでRubyやCoffeeScript問題を出題している@tbpgrです。 今回は、開発の現場にいるからこそ見えてくる「綺麗なコードと汚いコード」をテーマに書いてみます。 あなたのコードは綺麗ですか?それとも汚いですか? 綺麗なコ...

今週のPickUPレポート

新着記事

週間ランキング

CodeIQとは

CodeIQ(コードアイキュー)とは、自分の実力を知りたいITエンジニア向けの、実務スキル評価サービスです。

CodeIQご利用にあたって
関連サイト
codeiq

リクルートグループサイトへ