introducing-crystal
introducing-crystal
『 Introducing Crystal Programming Language 』の原稿を管理するリポジトリです。
必要なもの
- Ruby 2.7.0
- Bundler
- Redpen
ビルド方法
bundle install して bundle exec rake すればビルドできます。
$ bundle install --path=vendor/bundle
$ bundle exec rake -j
生成されたファイルは build ディレクトリ以下にあります。
$ ls build
docs/ introducing-crystal-print.pdf introducing-crystal-web.pdf
introducing-crystal-print.pdf は印刷用の PDF で、 introducing-crystal-web.pdf は Web 公開用の PDF です。 docs/ 以下には Jekyll で生成されたドキュメントがあります。
テスト
Redpen による文章のチェック等や crystal tool format によるフォーマットのチェックは bundle exec rake lint で実行できます。
$ bundle exec rake lint
Example テストやプロジェクトのテストは bundle exec rake test で実行できます。
$ bundle exec rake test
この2つが通るようにがんばってください。
文章の書き方
それぞれのディレクトリにある content.adoc に Asciidoc 形式で執筆してください。
Asciidoc 形式については次に挙げるリンクでも参考にしてください。
- Asciidoctor のユーザマニュアル: あらゆることが書いてありますが、長いので読むのがしんどいです。
- Asciidoc 簡易メモ: 日本語の記事です。よくまとまってます。
- Asciidoc 入門: 同じく日本語の記事です。
コードの挿入について
原稿にコードを挿入する場合は、Asciidoc の include 機能を利用してください。 これはコードと記事を分離して、コードに対してコンパイルができる状態を保つためです。
[source,crystal]
----
include::./examples/code.cr[]
----
コードはディレクトリの examples 以下に置いてください。
examples ディレクトリ以下に置いた Crystal のコードは bundle exec rake test の際にいくつか変換を施したのち実行されます。
変換のルールは以下の通りです。
式の後に # => のようなコメントが続く場合
1 + 2 # => 3
このように変換されます。
require "spec"
it "code.cr" do
(1 + 2).inspect.should eq("3")
end
期待する文字列に16進数の数値が含まれる場合、その部分は適当な16進数の文字列にマッチするものとして扱われます。 これは、インスタンスを inspect した際にオブジェクトのアドレスが表示されるので、それに対応するためです。
# => から始まる行の場合
begin
1 + 2
end
# => 3
このように変換されます。
require "spec"
it "code.cr" do
begin
1 + 2
end
.inspect.should eq("3")
end
式の後に # raises が続く場合
[1, 2][3] # raises IndexError (Index out of bounds)
このように変換されます。
require "spec"
it "code.cr" do
expect_raises(IndexError, "Index out of bounds") { [1, 2][3] }
end
括弧に囲まれた部分は省略できて、その場合はエラーメッセージに対して検査が行われません。
# tag::main[] と # end::main[]
# => を含む場合コード全体が it で囲まれることになるのですが、 def 等の定義はブロックの中に書けないのでブロックの位置を指定したい場合があります。 その場合は # tag::main[] というコメントと # end::main[] というコメントで囲ってください。
このコメントは Asciidoc でタグ領域の指定に使うものなので、 include した結果にも現れないので安心してください。
def foo
42
end
# tag::main[]
foo # => 42
# end::main[]
このように変換されます。
def foo
42
end
require "spec"
it "code.cr" do
(foo).inspect.should eq("42")
end
# output:
# output: で出力のテストができます。
puts "Hello, World!"
puts "Crystal"
# output:
# Hello, World!
# Crystal
# output: と # => や # raises は併用できません。
# tag::compileonly[]
ソースコード中に # tag::compileonly[] がある場合、そのコードは上記のテストは実行されず、コンパイルが通るか確認するだけになります。
# tag::compileonly[]
# end::compileonly[]
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)
Shards のプロジェクトについて
いくつかの章では説明のためにプロジェクトを作るかと思います。 その場合は projects ディレクトリ以下にプロジェクトを配置すると、 bundle exec rake test の際にプロジェクトのビルドとテストが実行されます。
ビルドとテストは、
Makefileが無い場合は、shardsとcrystal specを実行します。Makefileがある場合は、makeとmake testを実行します。
という風にして実行します。
rake lint ではチェックされないけど注意してほしい部分
- 全て小文字の
crystalという表記はコマンド名として、先頭が大文字の Crystal はプログラミング言語の名前として使い分けてください。
CI 用のコンテナのビルド方法
RedPen 1.10.4の .tar.gz を落としてきて vendor/ 以下に展開したあと、次のコマンドを実行します。
$ docker build -t makenowjust/techbookfest-build -f .circleci/images/build/Dockerfile .
introducing-crystal
- 16
- 3
- 5
- 0
- 0
- about 1 year ago
- January 10, 2018
Tue, 28 Oct 2025 02:21:42 GMT