ruby string immutability ruby-2.3

ruby - ¿Qué hace el comentario "frozen_string_literal: true"?



immutability ruby-2.3 (3)

En Ruby 3.0. Matz (el creador de Ruby) decidió congelar todos los literales de cadena por defecto.

Puedes usar en Ruby 2.x. Simplemente agregue este comentario en la primera línea de sus archivos.

# frozen_string_literal: true

El comentario anterior en la parte superior de un archivo cambia la semántica de los literales de cadena estática en el archivo. Los literales de cadena estática se congelarán y siempre devolverán el mismo objeto. (La semántica de los literales de cadena dinámica no cambia).

De esta manera tiene los siguientes beneficios:

Sin feo sufijo f. No hay error de sintaxis en Ruby anterior. Solo necesitamos una línea para cada archivo.

Por favor, lea este tema para obtener más información.

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

Este es el rspec rspec en mi directorio de proyectos.

#!/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é se pretende hacer con esto?

# frozen_string_literal: true


Mejora el rendimiento de la aplicación al no asignar nuevo espacio para la misma cadena, lo que también ahorra tiempo para las tareas de recolección de basura. ¿Cómo? cuando congela un literal de cadena (objeto de cadena), le está diciendo a Ruby que no permita que ninguno de sus programas modifique el literal de cadena (objeto).

Algunas observaciones obvias a tener en cuenta.

1. Al congelar los literales de cadena, no está asignando nuevo espacio de memoria para ello.

Ejemplo:

Sin comentario mágico asigna nuevo espacio para la misma cadena (Observe las diferentes ID de objeto impresas)

def hello_id a = ''hello'' a.object_id end puts hello_id #=> 70244568358640 puts hello_id #=> 70244568358500

Con un comentario mágico , ruby ​​asigna espacio solo una vez

# frozen_string_literal: true def hello_id a = ''hello'' a.object_id end puts hello_id #=> 70244568358640 puts hello_id #=> 70244568358640

2. Al congelar los literales de cadena, su programa generará una excepción al intentar modificar el literal de cadena.

Ejemplo:

Sin comentarios mágicos , puede modificar los literales de cadena.

name = ''Johny'' name << '' Cash'' puts name #=> Johny Cash

Con el comentario mágico , se generará una excepción cuando modifique literales de cadena

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

Siempre hay más para aprender y ser flexible:


# frozen_string_literal: true es un comentario mágico, admitido por primera vez en Ruby 2.3, que le dice a Ruby que todos los literales de cadena en el archivo están implícitamente congelados, como si se hubiera llamado a #freeze en cada uno de ellos. Es decir, si un literal de cadena se define en un archivo con este comentario, y llama a un método en esa cadena que lo modifica, como << , obtendrá RuntimeError: can''t modify frozen String .

El comentario debe estar en la primera línea del archivo.

En Ruby 2.3, puede usar este comentario mágico para prepararse para los literales de cadena congelados que son los predeterminados en Ruby 3 .

En Ruby 2.3 se ejecuta con el indicador --enable=frozen-string-literal , y en Ruby 3, los literales de cadena se congelan en todos los archivos. Puede anular la configuración global con # frozen_string_literal: false .

Si desea que un literal de cadena sea mutable independientemente de la configuración global o por archivo, puede prefijarlo con el operador unario + (teniendo cuidado con la precedencia del operador) o llamar a .dup :

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

También puede congelar una cadena mutable (sin congelar) con unario - .