2016-06-13 14 views
60

To jest binstub rspec w moim katalogu projektu.Co robi komentarz "frozen_string_literal: true"?

#!/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") 

Co to ma zrobić?

# frozen_string_literal: true 

Odpowiedz

86

# frozen_string_literal: true to magiczne komentarz, wspierany po raz pierwszy w Ruby 2.3, który mówi, że wszystkie Ruby literały ciągów znaków w pliku są niejawnie zamrożone, jakby #freeze został powołany na każdym z nich. To znaczy, jeśli literał łańcuchowy jest zdefiniowany w pliku z tym komentarzem, a ty wywołujesz metodę na tym łańcuchu, który ją modyfikuje, na przykład <<, otrzymasz RuntimeError: can't modify frozen String.

Komentarz musi znajdować się w pierwszym wierszu pliku.

W Ruby 2.3, można użyć tego magicznego komentarz do przygotowania zamrożonych napisowych będących domyślny w Ruby 3.

w Ruby 2.3 biegu z flagą --enable=frozen-string-literal, aw Ruby 3 literały łańcuchowe są zamrożone wszystkie pliki. Możesz zmienić ustawienie globalne na # frozen_string_literal: false.

Jeśli chcesz ciąg dosłownego być zmienny niezależnie od globalnej lub ustawienia dla pliku można poprzedzić go z jednoargumentowego + operatora (uważając z pierwszeństwa operatora) lub zadzwoń .dup na nim:

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

Można także zamrozić zmienny (niezamrożony) ciąg z unarnym -.

+1

Ważną rzeczą, którą należy zauważyć, jeśli chodzi o zamrażanie ciągów jest to, że [poprawia wydajność aplikacji] (https://bugs.ruby-lang.org/issues/8976#note-30). Zobacz także [tutaj] (https://blog.lucascaton.com.br/2016/01/19/what-is-frozen_string_literal-in-ruby/) –

+2

@ dave-schweisguth Nie powinniśmy spodziewać się '-" foo " "być tym samym, co' "foo" .freeze'? Kiedy sprawdzam '(-" foo ") .__ id__' Za każdym razem otrzymuję inną wartość, ale' 'foo" .freeze .__ id__' jest za każdym razem takie samo. Jakieś pomysły? – lilole

+0

Zastanawiam się, czy ta funkcja jest problemem, wydaje się, że jest ona wywoływana tylko z jednoargumentowym minusem. https://github.com/ruby/ruby/blob/trunk/string.c#L2572 – lilole