Ruby風に書ける&安心コンパイル!注目言語「Crystal」に触れてみよう


Ruby風に書ける&安心コンパイル!注目言語「Crystal」に触れてみよう

こんにちは。バックエンドエンジニアの銀シャリです。

今回は、バックエンド最新技術をつまみ食い的に試してみる連載の第二回目。

前回はWebエンジニア界隈で大きな盛り上がりを見せている言語「Elixir」を紹介しました。今回もまた同様に、昨年頃から注目されている言語、「Crystal(クリスタル)」について紹介します。

Rubyの文法で記述しながら、処理の高速化とコンパイルによるチェックで安全に開発を進めたい場合におすすめな言語です。

▼目次

Crystalとは?

Crystalは、Rubyにインスパイアされた文法と型推論を持った静的型付け言語。

2012年の後半にアルゼンチンのManas社の技術者であるAry Borenszweig氏を中心に「Rubyの良い所を限りなく維持した上でより早いコンパイル言語を作れないか」を目標として開発されました。

Crystalを導入しよう

それでは、実際にCrystalを導入してみましょう。
なお、今回インストールするソフトウェアのバージョンは以下の通りです。

  • crystal-lang:0.13.0

Crystalのインストール

インストールする際は、以下の公式手順が参考になります。

公式ドキュメントを日本語に翻訳したサイトもあります。翻訳者の方々ありがとうございます。

Macをお使いの方は、Hombebrewでインストールすると楽です。

brew update
brew install crystal-lang

Crystalにおいても、「crenv」という「rbenv」のようなパッケージマネージャーが用意されていますので、これを利用してインストールするとバージョンの管理は楽になりますね。

※ 事前に「anyenv」というツールをインストールしておく必要があります。

オンライン実行環境「Crystal-playground」でチェック

Crystalでは「Playground」と呼ばれる公式オンライン実行環境が用意されていますので、インストールしなくても簡単なコードを記述して試しに実行してみることができます。ちょっと試したい方にはちょうどいいですね。

Crystal:はじめの一歩

それでは、さっそくCrystalに触れてみましょう。

1. HelloWorldを表示してみよう

Crystalには標準のREPLはありませんので、先ほど紹介したPlaygroundか、実際にファイルを作成して実行していきましょう。

まずは定番のHelloWorldから。

以下の内容で、helloworld.crというファイルを作成してください。

puts "hello world!"

実行するには、以下のコマンドを実行します。

$ crystal helloworld.cr 
hello world!

コンソール出力できましたね?

実行可能なバイナリを作成するには、以下のように実行します。

$ crystal build helloworld.cr 
$ ./helloworld 
hello world!

2. サンプルを動かしてみよう

せっかくなので、抽象クラス・抽象メソッドを利用したサンプルを動かしてみましょう。

abstract.crという名前で以下のコードを保存します。

# クラス定義
abstract class Animal
  abstract def talk
end

class Dog < Animal
  def talk
    "ワン!"
  end
end

class Cat < Animal
  def talk
    "ニャン!"
  end
end

class Person
  getter pet

  def initialize(@name, @pet)
  end

  def introduce
    puts @name + "さんのペットは「" + @pet.talk + "」と鳴きます"
  end
end

# ここから処理開始
john = Person.new "John", Dog.new
peter = Person.new "Peter", Cat.new

john.introduce
peter.introduce

実行してみましょう。

$ crystal abstract.cr 
Johnさんのペットは「ワン!」と鳴きます
Peterさんのペットは「ニャン!」と鳴きます

上記のように出力されましたか?

同じ処理をRubyで記述すると以下のようなコードになります。

class Animal
end

class Dog < Animal
  def talk
    "ワン!"
  end
end

class Cat < Animal
  def talk
    "ニャン!"
  end
end

class Person

  def initialize(name, pet)
    @name = name
    @pet = pet
  end

  def introduce
    puts @name + "さんのペットは「" + @pet.talk + "」と鳴きます"
  end
end

john = Person.new "John", Dog.new
peter = Person.new "Peter", Cat.new

john.introduce
peter.introduce

記述に大きく差が無いことはお分かりいただけると思いますが、抽象クラス・抽象メソッドを定義していることで、Animalを継承したクラスを追加する場合に、コンパイルによるチェックが行われますのでより安全に開発を進められますね。

さてもう一つ、今度はメソッドのオーバーロードのサンプルです。

overload.crという名前で以下のコードを保存します。

class Person
  def initialize(name)
    @name = name
  end

  def setAge(age)
    @age = age
  end

  def setAge(year, month, day)
    span = Time.now.to_s("%Y%m%d").to_i - Time.new(year, month, day).to_s("%Y%m%d").to_i
    @age = span / 10000
  end

  def introduce
    puts "Hi, myname is " + @name + ". " + @age.to_s + " years old."
  end
end

john = Person.new "John"
john.setAge(21)
peter = Person.new "Peter"
peter.setAge(1982, 10, 5)

john.introduce
peter.introduce

実行してみましょう。

$ crystal overload.cr 
myname is John. 21 years old.
myname is Peter. 33 years old.

表示されましたか?

オーバーロードは、静的型付けでないRubyでは存在していません。しかし、オーバーロードを適切に利用することで、メソッド内のロジックが整理しやすくなるなどの効果が得られます。そのため、抽象クラスの例と同じように、安全に開発するうえでの利用価値はあるのではないでしょうか。

おわりに

Crystalのインストールから簡単なサンプルコードまでを紹介しましたが、いかがでしたか? 今年の飛躍がとても楽しみな言語、Crystalにご興味をお持ちになられた方はぜひこの機会に触ってみていただければと思います。

それでは!


この記事を書いた人

銀シャリ
銀シャリ バックエンドエンジニア 2015年入社
東京周辺でWebエンジニアをしている流浪のサーバーサイドエンジニア。
エンジニア応援し隊。