Rabbit Slide Show

Description

Crystal について

Text

Page: 1

Crystal
とみたまさひろ
2015-08-23
Crystal
Powered by Rabbit 2.1.6

Page: 2

Crystal
http://crystal-lang.org/
Crystal
Powered by Rabbit 2.1.6

Page: 3

Ruby風の言語
Crystal
Powered by Rabbit 2.1.6

Page: 4

Ruby風?
Crystal
Crystal
Ruby
静的 動的
型あり 型なし
コンパイル言語 スクリプト言語
Powered by Rabbit 2.1.6

Page: 5

Crystal プログラム
ふつーに Ruby
class Hoge
def foo
p "abc"
end
end
Hoge.new.foo #=> "abc"
Crystal
Powered by Rabbit 2.1.6

Page: 6

実行
% ruby hoge.rb
"abc"
% crystal hoge.rb
"abc"
Crystal
Powered by Rabbit 2.1.6

Page: 7

ベンチマーク
# フィボナッチ数列のN番目の値
def fib(n)
if n < 2
n
else
fib(n-1) + fib(n-2)
end
end
p fib(35)
Crystal
Powered by Rabbit 2.1.6

Page: 8

速い!
% time ruby fib.rb
9227465
real
0m2.275s
user
0m2.268s
sys
0m0.004s
% time crystal fib.rb
9227465
real
0m0.299s
user
0m0.236s
sys
0m0.056s
Crystal
Powered by Rabbit 2.1.6

Page: 9

コンパイルして実行ファイルを生成
% crystal build fib.rb --release
% ./fib
9227465
Crystal
Powered by Rabbit 2.1.6

Page: 10

さらに速い!
% time crystal fib.rb
9227465
real
0m0.299s
user
0m0.236s
sys
0m0.056s
% time ./fib
9227465
real
0m0.090s
user
0m0.088s
sys
0m0.000s
Crystal
Powered by Rabbit 2.1.6

Page: 11

RubyスクリプトをCrystalで実行
するだけで速くなる!?
Crystal
Powered by Rabbit 2.1.6

Page: 12

そんなうまい話はない
Crystal
Powered by Rabbit 2.1.6

Page: 13

Crystal ≠ Ruby
Crystal
Powered by Rabbit 2.1.6

Page: 14

文字と文字列
"A" - 文字列
'A' - 文字
"A"+"B" #=> "AB"
'A'+'B' #=> undefined method '+' for Char
Crystal
Powered by Rabbit 2.1.6

Page: 15

多倍長整数がない
整数演算の謎に見える挙動
0x7FFFFFFF.class
0x80000000.class
0x7FFFFFFF+1
0x7FFFFFFFi64+1
256*256*256
256**3
256*256*256*256
256**4
Crystal
#=>
#=>
#=>
#=>
#=>
#=>
#=>
#=>
Int32
Int64
-2147483648
2147483648
16777216
1.67772e+07
0
4.29497e+09
Powered by Rabbit 2.1.6

Page: 16

Crystal は Crystal として使おう
Crystal
Powered by Rabbit 2.1.6

Page: 17

拡張子は .rb じゃなくて .cr
Crystal
Powered by Rabbit 2.1.6

Page: 18

Crystalの特徴(Rubyと比較して)
Crystal
Powered by Rabbit 2.1.6

Page: 19

型
a = [1, 2, 3] #=> Array(Int32)
a.push 4
#=> OK
a.push "a"
#=> no overload matches 'Array(Int32)#push'
# with types String (コンパイル時エラー)
a = []
a = [] of Int32
Crystal
#=> Syntax error
#=> OK
Powered by Rabbit 2.1.6

Page: 20

メソッド
def hoge(a, b)
a + b
end
hoge("abc", "xyz")
hoge(1, 2)
hoge("abc", 2)
Crystal
#=> "abcxyz"
#=> 3
#=> コンパイル時エラー
Powered by Rabbit 2.1.6

Page: 21

コンパイル時エラー
% crystal build hoge.cr
Error in ./hoge.cr:7: instantiating 'hoge(String, Int32)'
hoge("abc", 2)
^~~~
in ./hoge.cr:2: no overload matches 'String#+' with types Int32
Overloads are:
- String#+(other : self)
- String#+(char : Char)
a + b
^
Crystal
Powered by Rabbit 2.1.6

Page: 22

オーバーロード
def hoge(a, b)
a + b
end
def hoge(a : String, b : Int)
a * b
end
hoge("abc", "xyz")
hoge(1, 2)
hoge("abc", 2)
Crystal
#=> "abcxyz"
#=> 3
#=> "abcabc"
Powered by Rabbit 2.1.6

Page: 23

変数に型はない
var = 123
var = 'a'
Crystal
Powered by Rabbit 2.1.6

Page: 24

複数の型の可能性
var = rand < 0.5 ? 123 : "abc"
var.size # Int にないのでエラー
var + 1
# String にないのでエラー
Crystal
Powered by Rabbit 2.1.6

Page: 25

ちゃんと型チェックすればエラーにならない
var = rand < 0.5 ? 123 : "abc"
if var.is_a? Int
var + 1
else
var.size
end
Crystal
Powered by Rabbit 2.1.6

Page: 26

静的
Crystal
Powered by Rabbit 2.1.6

Page: 27

静的
eval がない
クラス定義/メソッド定義は後勝ち
Crystal
Powered by Rabbit 2.1.6

Page: 28

メソッド定義は後勝ち
if rand < 0.5
def hoge
123
end
else
def hoge
"abc"
end
end
Crystal
# ← rand の値に関係なく無視される
#
#
# ← 常にこっちが有効
#
#
Powered by Rabbit 2.1.6

Page: 29

直感に反したり
def hoge
123
end
if false
def hoge
"abc"
end
end
hoge #=> "abc"
Crystal
Powered by Rabbit 2.1.6

Page: 30

その他
Crystal
Powered by Rabbit 2.1.6

Page: 31

名前付き引数
Rubyより自然かも
def hoge(n=123,
p [n, s]
end
hoge
hoge(789)
hoge(s: "xyz")
Crystal
s="abc")
#=> [123, "abc"]
#=> [789, "abc"]
#=> [123, "xyz"]
Powered by Rabbit 2.1.6

Page: 32

マクロ
macro define_method(name, content)
def {{name}}
{{content}}
end
end
define_method foo, 123
foo #=> 123
Crystal
Powered by Rabbit 2.1.6

Page: 33

プロジェクト雛形作成(Rails風?)
% crystal init app my_project
create my_project/.gitignore
create my_project/LICENSE
create my_project/README.md
create my_project/.travis.yml
create my_project/Projectfile
create my_project/src/my_project.cr
create my_project/src/my_project/version.cr
create my_project/spec/spec_helper.cr
create my_project/spec/my_project_spec.cr
Initialized empty Git repository in /tmp/my_project/.git/
Crystal
Powered by Rabbit 2.1.6

Page: 34

ライブラリ依存関係解決(Bundler風)
my_project% cat Projectfile
deps do
github "manastech/crystal-mysql"
end
my_project% crystal deps install
Cloning into '.deps/manastech-crystal-mysql'...
remote: Counting objects: 55, done.
remote: Total 55 (delta 0), reused 0 (delta 0), pack-reused 55
Receiving objects: 100% (55/55), 7.03 KiB | 0 bytes/s, done.
Resolving deltas: 100% (19/19), done.
Checking connectivity... done.
Crystal
Powered by Rabbit 2.1.6

Page: 35

ドキュメント作成(YARD風)
my_project% crystal doc
my_project% ls doc
Myproject.html css index.html js
Crystal
list.html
main.html
Powered by Rabbit 2.1.6

Page: 36

テスト(RSpec風)
my_project% crystal spec
.
Finished in 0.38 milliseconds
1 examples, 0 failures, 0 errors, 0 pending
Crystal
Powered by Rabbit 2.1.6

Other slides