Latest release 1.4.1
22 April 2022 - More release notes
構文
Crystal の構文は Ruby の影響をつよく受けています。そのため自然に読めて、簡単に書けます。そして、 Ruby 開発の経験があれば習得は容易でしょう。
# A very basic HTTP server
require "http/server"
server = HTTP::Server.new do |context|
context.response.content_type = "text/plain"
context.response.print "Hello world, got #{context.request.path}!"
end
puts "Listening on http://127.0.0.1:8080"
server.listen(8080)
型システム
Crystal は静的に型チェックされるプログラミング言語です。そのため、実行時にエラーを起こすのではなく、コンパイラが早期に型エラーを発見するでしょう。さらに、Crystal は型推論も備えています。ほとんどの場合、型注釈は必要ありません。
def shout(x)
# Notice that both Int32 and String respond_to `to_s`
x.to_s.upcase
end
foo = ENV["FOO"]? || 10
typeof(foo) # => (Int32 | String)
typeof(shout(foo)) # => String
Null 参照チェック
Crystal ではすべての型は nil を許容しません。そして nil を許容する変数は、その型と nil とのユニオン型となります。要するに、コンパイラはコンパイル時に自動的に null 参照をチェックしてくれる、ということです。これは1億ドルの損失から免れる助けになるでしょう。
if rand(2) > 0
my_string = "hello world"
end
puts my_string.upcase
このファイルを実行すると、こんな結果になります。
$ crystal hello_world.cr
Error in hello_world.cr:5: undefined method 'upcase' for Nil (compile-time type is (String | Nil))
puts my_string.upcase
^~~~~~
マクロ
Crystal はメタプログラミングに対する答えとして、強力なマクロシステムを備えています。この力は基本的なテンプレート処理から AST の分析や型の分析、さらには外部コマンドの実行までに及びます。
class Object
def has_instance_var?(name) : Bool
{{ @type.instance_vars.map &.name.stringify }}.includes? name
end
end
person = Person.new "John", 30
person.has_instance_var?("name") #=> true
person.has_instance_var?("birthday") #=> false
並列モデル
Crystal はファイバーと呼ばれる軽量スレッドを用いて、並列性を獲得しています。ファイバー同士は Go や Clojure のようなチャネルを用いて協調します。共有メモリやロックは用いません。
channel = Channel(Int32).new
total_lines = 0
files = Dir.glob("*.txt")
files.each do |f|
spawn do
lines = File.read_lines(f)
channel.send lines.size
end
end
files.size.times do
total_lines += channel.receive
end
puts total_lines
C バインディング
Crystal ではネイティブのライブラリを呼ぶため構文を持っており、低レベルのタスクの再実装は必要ありません。
# Fragment of the BigInt implementation that uses GMP
@[Link("gmp")]
lib LibGMP
alias Int = LibC::Int
alias ULong = LibC::ULong
struct MPZ
_mp_alloc : Int32
_mp_size : Int32
_mp_d : ULong*
end
fun init_set_str = __gmpz_init_set_str(rop : MPZ*, str : UInt8*, base : Int) : Int
fun cmp = __gmpz_cmp(op1 : MPZ*, op2 : MPZ*) : Int
end
struct BigInt < Int
def initialize(str : String, base = 10)
err = LibGMP.init_set_str(out @mpz, str, base)
raise ArgumentError.new("invalid BigInt: #{str}") if err == -1
end
def <=>(other : BigInt)
LibGMP.cmp(mpz, other)
end
end
依存関係の管理
Crystal のライブラリは Shards と呼ばれ、中央集権的なリポジトリを持たず Git で配布されます。shards コマンドではYAMLファイルで依存関係を指定できて、さらにそれらを取得してこれます。
name: my-project
version: 0.1
license: MIT
crystal: 1.4.1
dependencies:
mysql:
github: crystal-lang/crystal-mysql
Crystal のトップスポンサー
一覧はこちらいくつかの CI はこちらで実行されています
ブログ記事 (一部未翻訳)
リリースノート (一部未翻訳)
Crystal 1.4.1 is released! | 22 Apr 2022 | |
Crystal 1.4.0 is released! | 06 Apr 2022 | |
Crystal 1.3.2 is released! | 18 Jan 2022 | |
Crystal 1.3.1 is released! | 13 Jan 2022 | |
Crystal 1.3.0 is released! | 06 Jan 2022 | |
Crystal 1.2.2 is released! | 10 Nov 2021 | |
Crystal 1.2.1 is released! | 21 Oct 2021 | |
Crystal 1.2.0 is released! | 14 Oct 2021 | |
Crystal 1.1.1 is released! | 27 Jul 2021 | |
Crystal 1.1.0 is released! | 16 Jul 2021 |