[ruby] “frozen_string_literal : true”라는 주석은 무엇을합니까?
이것은 rspec
내 프로젝트 디렉토리 의 쓰레기통입니다.
#!/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: true
Ruby 2.3에서 처음으로 지원되는 마법의 주석으로, 파일에있는 모든 문자열 리터럴이 #freeze
각각에 대해 호출 된 것처럼 암시 적으로 고정되었음을 Ruby에 알려줍니다 . 문자열 리터럴이 댓글을 가진 파일에 정의되어있는 경우 즉, 그리고 당신이하는 등의 수정을, 해당 문자열에 대한 메소드를 호출 <<
, 당신은 얻을 것이다 RuntimeError: can't modify frozen String
.
주석은 파일의 첫 번째 줄에 있어야합니다.
Ruby 2.3에서는이 마법 설명 을 사용 하여 고정 된 문자열 리터럴을 Ruby 3의 기본값으로 준비 할 수 있습니다 .
Ruby 2.3에서는 --enable=frozen-string-literal
플래그를 사용하여 실행하고 Ruby 3에서는 모든 파일에서 문자열 리터럴이 고정됩니다. 로 전역 설정을 무시할 수 있습니다 # frozen_string_literal: false
.
전역 또는 파일 별 설정에 관계없이 문자열 리터럴을 변경할 수있게하려면 단항 +
연산자 앞에 접두사를 붙이 거나 (연산자 우선 순위에주의하여) 호출 .dup
할 수 있습니다.
# frozen_string_literal: true
"".frozen?
=> true
(+"").frozen?
=> false
"".dup.frozen?
=> false
unary로 변경 가능 (동결 해제) 문자열을 고정 할 수도 있습니다 -
.
답변
동일한 문자열에 새 공간을 할당하지 않아 응용 프로그램 성능이 향상되어 가비지 수집 작업 시간이 절약됩니다. 어떻게? 문자열 리터럴 (문자열 객체)을 고정하면 프로그램에서 문자열 리터럴 (객체)을 수정하지 않도록 Ruby에 지시합니다.
명심해야 할 몇 가지 명백한 관찰.
1. 문자열 리터럴을 고정하면 새로운 메모리 공간이 할당되지 않습니다.
예:
마술 주석이 없으면 동일한 문자열에 새 공간을 할당합니다 (인쇄 된 다른 객체 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
2. 문자열 리터럴을 고정하면 문자열 리터럴을 수정하려고 할 때 프로그램에서 예외가 발생합니다.
예:
magic comment가 없으면 문자열 리터럴을 수정할 수 있습니다.
name = 'Johny'
name << ' Cash'
puts name #=> Johny Cash
magic comment를 사용하면 문자열 리터럴을 수정할 때 예외가 발생합니다.
# frozen_string_literal: true
name = 'john'
name << ' cash' #=> `<main>': can't modify frozen String (FrozenError)
puts name
항상 배우고 융통성이 있어야합니다.
답변
루비 3.0. Matz (Ruby의 제작자)는 기본적으로 모든 문자열 리터럴을 고정하기로 결정했습니다.
Ruby 2.x에서 사용할 수 있습니다. 파일의 첫 줄에이 주석을 추가하십시오.
# frozen_string_literal: true
파일 맨 위의 주석은 파일에서 정적 문자열 리터럴의 의미를 변경합니다. 정적 문자열 리터럴은 고정되며 항상 동일한 객체를 반환합니다. (동적 문자열 리터럴의 의미는 변경되지 않습니다.)
이 방법은 다음과 같은 이점이 있습니다.
추악한 f- 접미사가 없습니다. 이전 Ruby에서는 구문 오류가 없습니다. 각 파일마다 한 줄만 있으면됩니다.
자세한 내용은이 주제를 읽으십시오.