GitHubリポジトリ フォーラム RSS-ニュースフィード

Crystal

人間とコンピュータのための言語

必要なものは全て揃っています

Crystalの標準ライブラリには、プロジェクトの作業をすぐに開始できる幅広いライブラリが用意されています。

# 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

address = server.bind_tcp(8080)
puts "Listening on http://#{address}"

# This call blocks until the process is terminated
server.listen

型システム

Crystalは静的型付け言語であり、型エラーはコンパイラによって早期に検出されるため、実行時の様々な型関連エラーを排除できます。

しかし、強力な型推論のおかげで、型注釈はほとんど必要ありません。これにより、コードはクリーンに保たれ、動的言語のように感じられます。

def shout(x)
  # Notice that both Int32 and String respond_to `to_s`
  x.to_s.upcase
end

# If `ENV["FOO"]` is defined, use that, else `10`
foo = ENV["FOO"]? || 10

puts typeof(foo) # => (Int32 | String)
puts typeof(shout(foo)) # => String

Null参照チェック

nil値は特別な型Nilで表され、可能性のあるnil値はNilを含むユニオン型を持ちます。

その結果、コンパイラはコンパイル時に値がヌル可能かどうかを判断できます。nil値の明示的な処理を強制することで、恐ろしい10億ドルのバグを防ぐことができます。

foo = [nil, "hello world"].sample

# The type of `foo` is a union of `String` and `Nil``
puts typeof(foo) # => String | Nil

# This would be a type error:
# puts foo.upcase # Error: undefined method 'upcase' for Nil

# The condition excludes `Nil` and inside the branch `foo`'s type is `String`.
if foo
  puts typeof(foo) # => String
  puts foo.upcase
end

構文

Crystalの構文はRubyから大きく影響を受けているため、自然に読みやすく、書きやすく、経験豊富なRuby開発者にとって学習曲線が低いという利点もあります。

class String
  def longest_repetition?
    max = chars
            .chunk(&.itself)
            .map(&.last)
            .max_by?(&.size)

    {max[0], max.size} if max
  end
end

puts "aaabb".longest_repetition? # => {'a', 3}

並行処理モデル

Crystalは、ファイバーと呼ばれるグリーン・スレッドを使用して並行処理を実現します。ファイバーは、共有メモリやロックに頼ることなく、チャネルを介して互いに通信します(CSP)。

channel = Channel(Int32).new

3.times do |i|
  spawn do
    3.times do |j|
      sleep rand(100).milliseconds # add non-determinism for fun
      channel.send 10 * (i + 1) + j
    end
  end
end

9.times do
  puts channel.receive
end

Cバインディング

Crystalでは、Cライブラリ用のバインディングを定義し、それらに呼び出しを行うことができます。利用可能な豊富なライブラリエコシステムを簡単に利用できます。

既に優れたライブラリがあるタスクのために、プログラム全体をCrystalで実装する必要はありません。

# Define the lib bindings and link info:
@[Link("m")]
lib LibM
  fun pow(x : LibC::Double, y : LibC::Double) : LibC::Double
end

# Call a C function like a Crystal method:
puts LibM.pow(2.0, 4.0) # => 16.0

# This example intentionally uses a simple standard C function to be succinct.
# Of course you could do *this specific* calculation in native Crystal as well:
# 2.0 ** 4.0 # => 16.0

マクロ

Crystalにおけるメタプログラミングへの対応策は、基本的なテンプレートとAST検査から、型検査や任意の外部プログラムの実行までを網羅する強力なマクロシステムです。

class Object
  def has_instance_var?(name) : Bool
    {{ @type.instance_vars.map &.name.stringify }}.includes? name
  end
end

class Person
  property name : String

  def initialize(@name)
  end
end

person = Person.new "John"
p! person.has_instance_var?("name") # => true
p! person.has_instance_var?("birthday") # => false

依存関係

Crystalライブラリは、中央リポジトリを持たない分散型依存関係マネージャーであるシャードにパッケージされています。

shard.ymlで定義された依存関係を読み取り、リポジトリからソースコードを取得します。

name: my-first-crystal-app
version: 1.0.0
license: Apache-2.0

authors:
- Crys <crystal@manas.tech>

dependencies:
  mysql:
    github: crystal-lang/crystal-mysql
    version: ~>0.16.0

development_dependencies:
  ameba:
    github: crystal-ameba/ameba

ニュース


スポンサーシップ

OpenCollectiveを通じて、3つの簡単なステップでCrystalスポンサーになりましょう

貢献
エンタープライズサポート

Crystalへのスポンサーシップは、あなたのブランドにとって素晴らしい踏み台となります

サポートを受ける
プロジェクトのために私たちを雇う

言語の開発者自身の専門知識を活用して、実装を導くことができます。

私たちを雇う

主要スポンサー

成功事例