prosource

루비: "frozen_string_literal: true"라는 코멘트는 무엇을 의미합니까?

probook 2023. 6. 2. 20:35
반응형

루비: "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

# frozen_string_literal: trueRuby 2.3에서 처음으로 지원되는 마법 댓글로, 파일의 모든 문자열 리터럴이 암시적으로 동결되었음을 Ruby에게 알려줍니다.#freeze그들 각각에게 불려갔었습니다.즉, 이 주석이 있는 파일에 문자열 리터럴이 정의되어 있고 다음과 같은 문자열을 수정하는 메서드를 호출하는 경우<<얻게 될 것입니다RuntimeError: can't modify frozen String.

문자열을 고정하면 의도하지 않은 문자열을 실수로 수정하여 발생하는 버그를 방지하고 성능을 향상시킬 수 있습니다.

마법의 설명처럼 frozen_string_literal 설명은 파일의 첫 번째 설명 섹션에 있어야 합니다.아이러니하게도 해당 binstub의 frozen_string_literal 주석은 binstub의 첫 번째 주석 섹션에 없으므로 무시됩니다.

Ruby 2.3에서는 이 매직 코멘트를 사용하여 Ruby 3에서 기본값으로 고정 문자열 리터럴을 준비할 수 있습니다.

Ruby 2.3에서는 다음을 사용하여 실행합니다.--enable=frozen-string-literal플래그 Ruby 3에서는 문자열 리터럴이 모든 파일에서 동결됩니다.다음을 사용하여 전역 설정을 재정의할 수 있습니다.# frozen_string_literal: false.

글로벌 또는 파일별 설정에 관계없이 문자열 리터럴을 변경할 수 있도록 하려면 해당 문자열 리터럴 앞에 unary를 붙이면 됩니다.+operator(operator precedence 주의) 또는 호출.dup실행 중:

# frozen_string_literal: true
"".frozen?
=> true
(+"").frozen?
=> false
"".dup.frozen?
=> false

유니언을 사용하여 가변(동결되지 않은) 문자열을 고정할 수도 있습니다.-.

출처: ruby/ruby에 정의된 magic_comment

동일한 문자열에 새 공간을 할당하지 않음으로써 응용 프로그램 성능을 향상시켜 가비지 수집 작업에 필요한 시간을 절약할 수 있습니다. 어떻게? 문자열 리터럴(문자열 개체)을 고정하면 프로그램이 문자열 리터럴(개체)을 수정하지 못하도록 Ruby에게 말합니다.

명심해야 할 몇 가지 분명한 관찰 사항.

문자열 리터럴을 고정하면 새 메모리 공간이 할당되지 않습니다.

예:

마법의 설명 없이 동일한 문자열에 새 공간 할당(인쇄된 다른 개체 ID 관찰)

def hello_id
  a = 'hello'
  a.object_id
end

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

마법 댓글을 사용하면 루비는 공간을 한 번만 할당합니다.

# frozen_string_literal: true

def hello_id
  a = 'hello'
  a.object_id
end

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

문자열 리터럴을 고정하면 프로그램에서 문자열 리터럴을 수정할 때 예외가 발생합니다.

예:

마법의 설명 없이 문자열 리터럴을 수정할 수 있습니다.

name = 'Johny'
name << ' Cash'

puts name     #=> Johny Cash

마법설명을 사용하면 문자열 리터럴을 수정할 때 예외가 발생합니다.

# frozen_string_literal: true

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

puts name      

항상 배울 점과 유연성이 더 많습니다.

Ruby 3.0에서.Matz(Ruby의 작성자)는 기본적으로 모든 String 리터럴을 동결하기로 결정했습니다.

EDIT 2019: 그는 냉동 문자열 리터럴을 루비 3.0의 기본값으로 만드는 아이디어를 포기하기로 결정했습니다(출처: https://bugs.ruby-lang.org/issues/11473#note-53)


Ruby 2.x에서 사용할 수 있습니다. 파일의 첫 줄에 이 설명을 추가하기만 하면 됩니다.

# frozen_string_literal: true

파일 맨 위에 있는 위의 설명은 파일에서 정적 문자열 리터럴의 의미를 변경합니다.정적 문자열 리터럴이 고정되고 항상 동일한 개체를 반환합니다.(동적 문자열 리터럴의 의미는 변경되지 않습니다.)

이 방법에는 다음과 같은 이점이 있습니다.

추한 f-suffix는 없습니다.이전 Ruby에 구문 오류가 없습니다.우리는 각 파일마다 줄만 있으면 됩니다.

자세한 내용은 이 항목을 참조하십시오.

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

언급URL : https://stackoverflow.com/questions/37799296/ruby-what-does-the-comment-frozen-string-literal-true-do

반응형