🎉
[Feature #20205] frozen_string_literal をデフォルトで有効にするチケット
[Feature #20205] Enable frozen_string_literal
by default
-
frozen_string_literal
をデフォルトで有効にするチケット - いくつかポイントがあるんですがこの機能自体がかなり強い非互換になるので以下のような移行パスを提案している
- Release R0: 非推奨警告を導入(非推奨警告が有効な場合のみ)
- Release R1: 設定に関係なく非推奨警告を表示する
- Release R2:
frozen_string_literal
をデフォルトで有効にする - NOTE: これらの移行パスは具体的にどういうバージョンで適用されるのかはまた別の話
- また既に非推奨警告の実装は Shopify 側で実装しているらしい
- https://github.com/Shopify/ruby/pull/549
- かいつまむと以下のような対応らしい
-
#frozen_string_literal: true
または#frozen_string_literal: false
が定義されているファイルにはなにも影響がない -
#frozen_string_literal
がないファイルではコンパイル時にputstring
の変わりにputchilledstring
が使用される -
putchilledstring
では文字列をマークしておき、文字列が変更されたら警告を出すようにいなっている
-
- 互換性に関する話としては以下のようなオプションを指定する事で互換性を保つことができる、とも書いてある
RUBYOPT="--disable=frozen_string_literal"
- ちなみに既存で
--enable=frozen_string_literal
を指定する事ができる
-
frozen_string_literal
を有効にする利点としてパフォーマンスと意図しない変更を防ぐ目的がある - パフォーマンスに関しては https://bugs.ruby-lang.org/issues/20205#note-4 にいくつかのライブラリのベンチマークが載っている
- 最大で5%のパフォーマンスが改善されている
- 逆に -6% 遅くなっているケースもある
- 後続の検証は https://bugs.ruby-lang.org/issues/20205#note-34 になる
- 意図しない変更、は例えば以下のようなコードとかですね
HEADER = "<html><body>"
def generate
output = HEADER # no `.dup`
output << "<p>test</p>" # HEADER の値が変わってしまう
# ...
end
- 他の論点としては
--enable-frozen-string-literal
を使ったほうがいいのではないか、みたいな議論もされている - 最終的にはこの対応自体は matz が同意しているので次の Ruby のバージョンから何かしらの対応が入りそう
- いつになるかは置いといてまた Ruby 3.0 のキーワード引数と同じぐらいの対応が必要になってきそうですねー
Discussion