CHANGELOG v0.28.0
2019/04/17
[原文]
言語仕様
(破壊的変更) Enum
の定義内でメンバーの区切りに空白文字を使用できなくなり、改行文字、;
、,
だけが使用可能になった。ただし、,
の使用は非推奨であり、フォーマッタによって ;
に置き換えられる(#7607、#7618)
原文では、,
は改行文字に置き換えられるとなっているが、ソースの変更内容を見る限り ;
に置き換わるっぽい。(brew版が来ていないので未確認)
開始条件や終了条件のない範囲オブジェクト(例:array[5..]
)を生成可能に(#7179)
配列のある要素から後ろ全部が欲しい時に array[5..-1]
みたいな不自然な指定をしなくてもよくなった。
offsetof(Type, @ivar)
構文を追加(#7589)
その型がメモリに格納される際に指定したインスタンス変数が使用するメモリ番地のオフセットを返す。一部のCライブラリで必要になるらしい。
マクロ
指定された型の注釈(anotation
)全てを取得するための Type#annotations
を追加。(#7326)
これまでにも注釈を取得する Type#annotation
があったものの、指定された型の注釈が複数あった場合に、最後に指定されたものしか取得できなかった。
ArrayLiteral#sort_by
を追加(#3947)
Array#sort_by
と同様の操作を、マクロ内の ArrayLiteral
オブジェクトに対しても実行可能に。
標準ライブラリ
(破壊的変更) フラグ注釈された Enum
型で、Enum.from_value
を使って None
を生成できるようになった(#6516)
フラグ注釈された Enum
(※)として定義された F
型で、F.from_value 0
を実行すると、これまで例外を返していたが、この変更によって F::None
を返すようになった。
※: @[Flags]
注釈付きで Emun
を定義すると、Enum
の各メンバーをビットフラグのように扱って複数のフラグの重ね合わせを表現できるようになる。フラグ値が 0
ならどのフラグも立っていない状態(None
)になって然るべき
(破壊的変更) PartialComparable
に非推奨である旨の注釈を追加(#7664)
その機能は Comparable
に統合されているとのこと。
(性能改善) DWARF 形式デバッグ情報の行番号デコードを最適化(#7413)
Signal::CHLD.reset
が以前のハンドラをクリアできていなかったのを修正(#7409)
Object.getter?
マクロ と Object.property?
マクロの lazy 版を追加(#7322)
getter
や property
にブロックを指定すると、ゲッタメソッドを初めて呼び出したタイミングでブロックを評価した結果でインスタンス変数が初期化される。その仕組みが、getter?
と property?
にも追加された。
ゲッタメソッドが呼び出された時点で、インスタンス変数が nil
だった場合に、ブロックが評価されるような実装になっているので、property?(a : Int32) { 0 }
などのようにブロックで初期値を与えると、明示的に foo.a = nil
と nil
を代入したとしても、次回 foo.a
を呼ぶと 0
が返される。
Comparable#<=>
の返り値として、-1
、0
、1
以外の値も許容するようにした(#7277)
#<=>
の比較を、数値の大小で比較するような場合に
def param : Int32
#...
end
def <=>(other : self)
self.param - other.param
end
と書けるようになって非常に楽。
API ドキュメントのサンプルコードに欠けていた require
文を追加(#7564)
複数箇所のサンプルコードを修正 (#7569, thanks @maiha)
実行するとエラーになったり、実際の出力と齟齬があるサンプルコードなどが多数修正された。
@[Flags]
と @[Link]
注釈に関するドキュメントを追加(#7665)
Bool
型のドキュメントを追加(#7651)
GLIBC_PRIVATEシンボルであるスレッドローカルな $errno
の使用を避けるよう改修(#7496)
標準ライブラリ内の #to_s
と #inspect
が全て同じ型定義を持つよう修正(#7528)
#to_s
はオブジェクトの文字列表現(String
型)を返す。文字列表現の定義は #to_s(io :IO)
で、引数として与えられた IO
オブジェクトに書き込むことで行う。p foo
などで使用される #inspect
と #inspect(io : IO)
の関係も同じ。
これらの定義が、標準ライブラリを通じて def to_s : String
、def to_s(io : IO) : Nil
、def inspect : String
、def inspect(io : IO) : Nil
に統一された。自作の型でもこれに倣うのが吉。
数値
(破壊的変更) Int#/
が v0.29.0 からは Float
型の結果を返すようになるため、整数として除算結果を取得したい場合は Int#//
を使用するようにとのメッセージを追加(#7639)
Number#inspect
が型を明示しないように修正(#7525)
v0.24.0 で行われた修正が撤回された形。
Int#leading_zeros_count
と Int#trailing_zeros_count
を追加(#7520)
それぞれ、数値を2進数表記した際に先頭並ぶ0の数と末尾に並ぶ0の数を返す。
a = "00001000".to_i8(base : 2)
#=> 8
a.leading_zeros_count
#=> 4
a.trailing_zeros_count
#=> 3
ただし、BigInt
に関しては、#leading_zeros_count
が実装されていない。可変長の整数に対しては #leading_zeros_count
特定できないため。
Big*
系の数値型に欠けていた各種メソッドを追加(#7638)
#floor
、#ceil
、#trunc
、#//
や、BigInt
に対する &(+|-|*|**)
演算子など。
OverflowError
のメッセージを改善(#7375)
テキスト
(性能改善) 文字列がASCII文字しか含まない場合の String#compare
の処理を改善(#7352)
数値を人間が読みやすい形式にする Number#format
、Number#humanize
、Int#humanize_bytes
メソッドを追加(#6314)
ls
や df
コマンドに -h
オプションをつけた時のように、大きなもしくは小さな数値を K
や G
といった単位をつけて読みやすくしてくれるっぽい。
バイトに関しては、10の3乗を基準とするSI系接頭辞(KB
、GB
、TB
など)と、2の10乗(1024)を基準とするIEC系接頭辞(KiB
、GiB
、TiB
など)を選択可能。
String#rchop?
と String#lchop?
を追加(#7328)
文字列の末尾や先頭から引数として与えられた文字列(文字)を削除する#rchop
、#lchop
は、指定された端が引数にマッチしなかった場合にレシーバ文字列をそのまま返すが、こちらは実際に削除が行われた場合のみ削除後の文字列を返し、そうでない場合は nil
を返す。
String#camelcase
と String#underscore
に options
引数を追加(#7374)
次項の Unicode::CaseOptions
を指定できる。
Unicode::CaseOptions
のドキュメント追加(#7513)
テュルク語など、特有の大文字小文字変換規則をもった言語対応のためのオプション。
String#each_line
、IO#each_line
のドキュメントとスペックを改善 (#7419)
コレクション
(破壊的変更) Array#sort
が #<=>
メソッドだけを使用するようなり、部分的に比較可能な場合に #<=>
が nil
を返せるようにした(#6611)
このPRだけでいくつかの変更が行われている。
- これまで
#<
と#<=
を使用していたArray#sort
の実装が、ドキュメント通り、#<=>
だけを使用するように変更された。 Comparable
とPartialComparable
が機能的に統語され、#<=>
がnil
を返せるようになった。通常、返り値nil
は2つのオブジェクトの型を比較できない場合に使用される。一方、2つのオブジェクトが同じ型な場合も、通常比較可能であるが、例外的に比較できないような場合(PartialComparable
)にも利用できる。例としてはFloat
同士の比較(原則比較可能だが、NaN
が絡むと比較できなくなる)など。Array#sort
と関連したメソッドで#<=>
がnil
を返した際の処理が追加され、そうした場合は例外を発するようになった。Number <=> Number
はNaN
が絡んだ場合にnil
を返すが、Int <=> Int
がnil
を返すことがないよう最適化された。
(破壊的変更) Iterator#rewind
をなくして #cycle
を実装(#7440)
これまで、Iterator
モジュールにはイテレータのインデックスを先頭に戻す #rewind
が抽象メソッドとして定義されていて、Iterator
を mix-in しようとする型はそれぞれに #rewind
実装しなければならなかった。
ただ、Iterator
であっても #rewind
の利用が想定されない場合もあり、また #rewind
を使うにしても、最後の要素まで到達した際に先頭へ戻る用途でしか使われない場合も多い。
そのため、Iterator
から #rewind
の定義が取り除かれ、代わりに #cycle
が実装された。#cycle
は要素を内部配列として保持することで、終端まで到達した後、先頭へ戻ることが可能なイテレータオブジェクトを返す。
a = [0,1,2]
cycled_s = a.each.cycle
cycled_s.next => 0
cycled_s.next => 1
cycled_s.next => 2
cycled_s.next => 0
cycled_s.next => 1
# ....
このことにより、Iterator
利用時に個別の #rewind
を定義する必要がなくなり、標準ライブラリの各所からコードがかなり削減されている。
なお、バッファIO周りの #rewind
は個別に残されているので、ファイルの読み込み中にオフセットを先頭に戻すような利用は可能。
(性能改善) Enumerable#each_cons
で再利用バッファに Deque
も使えるようにした(#7233)
これまでは reuse
引数で指定する再利用バッファとして Array
オブジェクトしか指定できなかったが、Deque
オブジェクトも利用できるようになった(Deque
は Array
比べて先頭や末尾への追加/削除のパフォーマンスが高いので恩恵を受けられそう)
Iterator#cons
も同じ形式で Deque
オブジェクトを指定できるようになっている。
(性能改善) Range#bsearch
内の / 2
を >> 1
へ変更することで高速化(#7531)
LLVMの仕様上、符号付き整数の割り算はビットシフトと比べるとパフォーマンスがよろしくないらしい。
要素の型がプリミティブ型でない場合の Slice#clone
の挙動を修正し、深いコピーを行うように(#7591)
これまでは、プリミティブな型(固定長の数値型)以外を要素として持つスライスだと #clone
実行時にエラーが出ていた。
ついでに(?)、#clone
が深いコピーの結果を返す(各要素に対して #clone
を呼ぶ)ように修正されている。ちなみに、#dup
が浅いコピー。(おそらく、要素の型が #clone
を実装していないとエラーになると思われる。未検証)
Indexable#zip
と Indexable#zip?
を Enumerable
へ移動し、引数として Indexable
、Iterable
、Iterator
オブジェクトを幾つでも指定できるようにした(#7453)
プルリクエストのサンプルコードを見てると色々できそう。
Slice#[](Range)
を追加(#7439)
Array
と String
に該当する要素がまったくなかった際に nil
を返す #[]?(Range)
を追加(#7338)
Set#add?
を追加(#7495)
引数として渡されたオブジェクトが実際に追加されたら true
を、すでに同じ値を持っていて状態が変かしなかったら false
を返す。
要素の順序に関する Hash
のドキュメントを改善(#7594)
シリアライズ
(破壊的変更) YAML#libyaml_version
の返り値の型を SemanticVersion
へ変更(#7555)
バージョンの大小関係を SemanticVersion
型でチェックするようになった。普通に使ってる分にはあまり影響はないかと。
libxml2 2.9.9 のサポートを修正(#7477)
libyaml 0.2.2 のサポートを修正(#7555)
BigDecimal.from_yaml
を追加(#7398)
時刻/時間
(破壊的変更) Time
型のコンストラクタ名を変更。Time.now
は非推奨となり、Time.utc
もしくは Time.local
の使用を推奨(#5346、#7586)
(破壊的変更) 日数やその他の単位で時刻を変更する Time#add_span
の名前を Time#shift
へ変更(#6598)
(破壊的変更) Time#date
が Tuple
({year, month, day}
)を返すよう変更。(#5822)
これまでのように Time
オブジェクトが必要な場合は、Time#at_beginning_of_day
を使う。
Windows でのモノトニック時刻に関するバグを修正(#7377)
Time
型のメソッドを改善(#6581)
年、月、日を与えると、西暦1年1月1日からの経過日数を返してくれる Time.absolute_days
と、現在時刻から年、月、日、および年内の通算日数を返してくれる Time#year_month_day_day_year
(共に protected メソッド)の内部処理が改善された。
ファイル
(破壊的変更) IO#flush_on_newline
を廃止、TTYデバイスの時も sync
を使う(#7470)
Path
型を追加(#5635)
Ruby の Pathname
クラスのような、ファイルパスを操作する型ができた。
ネットワーク
(破壊的変更) HTTP::Multipart
を MIME::Multipart
に変更(#7085)
(破壊的変更) OAuth2エラー字のJSONパースを廃止(#7467)
(破壊的変更) RequestProcessor
の再利用ロジックを修正(#7055)
(破壊的変更) HTTP.default_status_message_for(Int)
を HTTP::Status.new(Int).description
で置き換え(#7247)
(破壊的変更) URI
の実装上の問題を修正(#6323, thanks @straight-shoota)
URI#opaque
メソッドは URI#path
に統合し、Nil
を返さないように。
#parse
/#to_s
の正規化とデフォルトポートの扱いを変更。
OpenSSL ソケットへの書き込みバッファ処理を修正(#7460)
HTTP::Server#bind_*
内のメモリリークを修正(#7197)
IO
の閉じ忘れ。
HTTP::Request#remote_address
を追加(#7610)
HTTP::Status
と Response#status
を追加(#7247、#7682)
OAuth 2.0 のリソースオーナーパスワードに対応(#7424)
クッキー内のIISの日付形式に対応(#7405)
IO::Syscall#wait_readable
と IO::Syscall#wait_writable
を許可(#7366)
HTTP::Client
のスペックを、タイムアウト後にサーバレスポンスを書かないよう変更(#7402)
musl 向けに TCP::Server
のスペックを修正(#7484)
暗号化
(破壊的変更) OpenSSL::HMAC
の digest
/hexdigest
におけるアルゴリズム指定に、シンボルではなく OpenSSL::Algorithm
型を使用するよう変更し、LibCrypt の PKCS5_PBKDF2_HMAC
メソッドに対応(#7264)
並行処理
マルチスレッド対応GCを追加(#7546)
-D preview_mt
付きでコンパイルすると利用可能。
bdw-gc にマルチスレッド対応パッチを適用(#7622)
Fiber::StackPool
を Fiber
から独立させるよう改修(#7417)
IO::Syscall
を IO::Evented
として改修(#7505)
システム
execvp
エラーメッセージにコマンド名と引数を追加(#7511)
ファイバ内のシグナル処理を改修(#7469)
Spec
スペックの実行中に CTRL+C
で中断する際の処理を改善(#7426)
各スペックの前に Fiber.yield
を実行して、シグナル処理するタイミングを設けている。これがないと、IOウェイトなどが発生して処理ファイバが切り替わるタイミングまで中断できない。
マルチスレッドに対応すれば不要になるだろう、とのこと。
pending
や it
の引数に定数を指定できるよう修正(#7646)
コンパイラ
(性能改善) --threads=1
が指定された際に fork や spawn をしないよう変更(#7397)
require ファイルが存在しない場合に投げられる例外を修正(#7386)
多重代入で代入先に定数があった場合のコンパイラ内部エラーを修正(#7468)
->foo.[]
やその他演算子のパースや挙動を修正(#7334)
asm
のパースで3連続コロン(:
)と変数が指定された際の処理を修正(#7627)
オフセットインデックスが更新されずに無限ループに陥っていた模様。
非推奨な(@[Deprecated]
が付けられた)メソッドの使用に警告を出すようにするオプトインのコンパイルフラグを追加(#7596、#7626、#7661)
静的ライブラリの検索先に CRYSTAL_LIBRARY_PATH
を追加(#7562)
未定義のメソッドや変数を使用しようとした際のエラーメッセージに、スコープ(with ... yield
スコープを含む)を表示するよう改善(#7384)
yield
で実行されるブロックから break
しようとした際に、エラーメッセージ中で next
を使用するよう提示するようにした(#7406)
コンパイラコンフィグでLinux 環境を取得できるようにした(#7479)
残っていた //
と &
演算子への対応(#7628)
Crystal::Config.version
が read_file
マクロを使用するよう改修(#7081)
マクロのスペックを外部コマンドを実行しないよう書き直し(#6962)
内部的なtypoを修正(#7592)
セマンティクス
as
/as?
とユニオン型に由来するいくつかの問題を修正(#7475)
同名のメソッドに、インスタンス化されていないジェネリック型(Foo
)を引数とする定義と、インスタンス化されたジェネリック型(Foo(Int32)
)を引数とする定義がった場合に、正しくメソッドが選択されるようにした(#7537)
def foo(a : Foo)
end
def foo(a : Foo(Int32))
end
みたいな時に、Foo(Int32)
型の引数が後者のメソッドへ渡されるようになった。
同名のメソッドに、明示的に指定した型を引数とする定義と、フリー変数で指定した型を引数とする定義があった場合に、正しくメソッドが選択されるようにした(#7536、#7580)
def foo(a : T.class) forall T
end
def foo(a : Int32.class)
end
みたいな時に、foo(Int32)
が後者のメソッドへを呼ぶようになった。
def foo(a : T) forall T
end
def foo(a : Array(T)) forall T
end
みたいな時も、Array(Int32)
型の引数が後者のメソッドへ渡されるようになっている。
initialize
が protected
として宣言された場合に、new
がprotected
として定義されるようにした(#7510)
名前付き引数の型マッチングを修正(#7529)
Proc
型のマッチングが、返り値の型に対して寛容になった(#7527)
これまでは、以下のようなコードがエラーになっていた。
class Foo
@bar : Proc(String, Nil)
@bar = ->(a : String) { 1 }
end
@bar
は文字列を引数に取り、なにがしかの操作をするが返り値を必要としないことを明示した Proc
型。一方、代入した Proc
オブジェクトは、ブロック内の最後の式の評価が 1
なため、コンパイラからは Proc(String, Int32)
型に見えてしまう。
今回の変更により、返り値が Nil
型である Proc
型は、引数の型が同じであれば、ブロックの評価結果が何型であろうと受け入れられるようになった。
言い換えれば、コンパイラは Proc
型の返り値には頓着しない、という実装になっている。
Proc
に対する再帰的なエイリアス指定のパース処理を修正(#7568)
Tools
travis.yml
内でユーザに対してフォーマッタを実行するよう提案(#7138)
ただしデフォルトはコメントアウト状態。
フォーマッタ
1\n.as(Int32)
のフォーマッティングを修正(#7347)
ネストした配列要素のフォーマッティングを修正(#7450)
Enum
とコメントのフォーマッティングを修正(#7605)
フォーマッティング対象を絶対パスDe指定した際のCLI処理を修正(#7560)
ドキュメント生成
private
な定数を含まないように修正(#7575)
Crystal
に内蔵された定数が含まれるよう修正(#7623)
crystal docs
コマンド用のコンパイルフラグを追加(#6668、#7438)
@[Deprecated]
注釈が付いている場合に Deprecated
タグを表示するようにした(#7653)
Playground
可読性を上げるためのフォントウェイトの変更(#7552)
その他
CIの強化と掃除(#7359、#7381、#7388、#7387、#7390、#7622)
最近の Docker イメージで使用する 64bit Linux版パッケージのスモークテスト(#7389)
git の pre-commit hook について CONTRIBUTING.md
で言及(#7617)
ソースコードの各所でスペルミスを修正(#7361)
ソースコードの各所で String
リテラルの代わりに Char
リテラルを使用(#6237)
1文字のリテラルであれば Char
リテラルの方がパフォーマンスが良い。