web-dev-qa-db-fra.com

Que fait le commentaire "frozen_string_literal: true"?

C'est le rspec binstub dans le répertoire de mon projet.

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

Qu'est-ce que cela est destiné à faire?

# frozen_string_literal: true
165
messanjah

# frozen_string_literal: true est un commentaire magique, supporté pour la première fois dans Ruby 2.3, qui indique à Ruby que tous les littéraux de chaîne du fichier sont gelés implicitement, comme si #freeze avait été appelé sur chacun d'eux. Autrement dit, si un littéral de chaîne est défini dans un fichier avec ce commentaire et que vous appelez une méthode sur cette chaîne qui la modifie, telle que <<, vous obtiendrez RuntimeError: can't modify frozen String.

Le commentaire doit être sur la première ligne du fichier.

Dans Ruby 2.3, vous pouvez utiliser ce commentaire magique préparer les littéraux de chaîne gelés comme valeurs par défaut dans Ruby 3.

Dans Ruby 2.3, exécutez l’indicateur --enable=frozen-string-literalet dans Ruby 3, les littéraux de chaîne sont figés dans tous les fichiers. Vous pouvez remplacer le paramètre global avec # frozen_string_literal: false.

Si vous voulez qu'un littéral de chaîne soit modifiable quel que soit le paramètre global ou par fichier, vous pouvez le préfixer avec l'opérateur unaire + (en faisant attention à la priorité des opérateurs) ou d'appeler .dup:

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

Vous pouvez également geler une chaîne mutable (non gelée) avec unary -.

244
Dave Schweisguth

Dans Ruby 3.0. Matz (le créateur de Ruby) a décidé de figer tous les littéraux de chaîne par défaut.

Vous pouvez utiliser dans Ruby 2.x. Ajoutez simplement ce commentaire dans la première ligne de vos fichiers.

# frozen_string_literal: true

Le commentaire ci-dessus en haut d'un fichier modifie la sémantique des littéraux de chaîne statiques du fichier. Les littéraux de chaîne statiques seront gelés et renverront toujours le même objet. (La sémantique des littéraux de chaîne dynamiques n'est pas modifiée.)

Cette manière a les avantages suivants:

Pas de f-suffixe laid. Aucune erreur de syntaxe sur Ruby plus ancien. Nous n'avons besoin que d'une ligne pour chaque fichier.

Veuillez lire ce sujet pour plus d'informations.

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

15
Alexandr

Il améliore les performances des applications en n'allouant pas de nouvel espace pour la même chaîne, ce qui permet également de gagner du temps pour les tâches de nettoyage de mémoire. Comment? Lorsque vous gèlez un littéral de chaîne (objet chaîne), vous dites à Ruby de ne laisser aucun de vos programmes modifier le littéral de chaîne (objet).

Quelques observations évidentes à garder à l'esprit.

1. En gelant les littéraux de chaîne, vous ne lui allouez pas un nouvel espace mémoire.

Exemple:

Sans commentaire magique alloue un nouvel espace pour la même chaîne (observez les différents ID d'objet imprimés)

def hello_id
  a = 'hello'
  a.object_id
end

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

Avec un commentaire magique , Ruby alloue de l'espace une seule fois

# frozen_string_literal: true

def hello_id
  a = 'hello'
  a.object_id
end

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

2. En gelant les littéraux de chaîne, votre programme lève une exception lorsque vous essayez de modifier le littéral de chaîne.

Exemple:

Sans commentaire magique , vous pouvez modifier les littéraux de chaîne.

name = 'Johny'
name << ' Cash'

puts name     #=> Johny Cash

Avec un commentaire magique , une exception sera déclenchée lorsque vous modifiez des littéraux de chaîne.

# frozen_string_literal: true

name = 'john'
name << ' cash'

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

Il y a toujours plus à apprendre et à être flexible:

8
imechemi