web-dev-qa-db-ja.com

コメント "frozen_string_literal:true"は何をしているのですか?

これは私のプロジェクトディレクトリのrspec binstubです。

#!/usr/bin/env Ruby
begin
  load File.expand_path("../spring", __FILE__)
rescue LoadError
end
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'rspec' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
  Pathname.new(__FILE__).realpath)

require "rubygems"
require "bundler/setup"

load Gem.bin_path("rspec-core", "rspec")

これは何をするつもりですか?

# frozen_string_literal: true
151
messanjah

Ruby 3.0ではMatz(Rubyの作成者)は、すべての文字列リテラルをデフォルトで固定することにしました。

あなたはRuby 2.xで使うことができます。ファイルの最初の行にこのコメントを追加してください。

# frozen_string_literal: true

ファイルの先頭にある上記のコメントは、ファイル内の静的文字列リテラルの意味を変更します。静的文字列リテラルは固定され、常に同じオブジェクトを返します。 (動的文字列リテラルの意味は変わりません。)

この方法には次のような利点があります。

醜いfサフィックスはありません。古いRubyでも構文エラーはありません。各ファイルに1行だけ必要です。

詳しくは、このトピックを読んでください。

https://bugs.Ruby-lang.org/issues/8976

13
Alexandr

同じ文字列に新しい領域を割り当てないことでアプリケーションのパフォーマンスが向上します。これにより、ガベージコレクションの雑用の時間も節約できます。どうやって?あなたが文字列リテラル(文字列オブジェクト)をフリーズするとき、あなたのプログラムのどれも文字列リテラル(オブジェクト)を修正しないようにRubyに言っています。

覚えておくべきいくつかの明白な観察。

1.文字列リテラルを凍結しても、新しいメモリスペースを割り当てることはできません。

例:

マジックコメントなしは同じ文字列に新しいスペースを割り当てます(印刷された異なるオブジェクトIDに注意してください)

def hello_id
  a = 'hello'
  a.object_id
end

puts hello_id   #=> 70244568358640
puts hello_id   #=> 70244568358500

マジックコメントの場合、Rubyは一度だけスペースを割り当てます

# frozen_string_literal: true

def hello_id
  a = 'hello'
  a.object_id
end

puts hello_id   #=> 70244568358640
puts hello_id   #=> 70244568358640

2.文字列リテラルを凍結することによって、文字列リテラルを変更しようとすると、プログラムは例外を発生させます。

例:

マジックコメントがなくても、文字列リテラルを変更できます。

name = 'Johny'
name << ' Cash'

puts name     #=> Johny Cash

マジックコメントでは、文字列リテラルを変更すると例外が発生します。

# frozen_string_literal: true

name = 'john'
name << ' cash'

puts name      #=> `<main>': can't modify frozen String (FrozenError)

習得して柔軟にすることが常にあります。

4
imechemi