Saltar al contenido

¿Es realmente malo usar makeatletter y makeatother en un paquete o archivo de clase?

Solución:

En primer lugar, makeatletter es innecesario en .sty o .cls archivos, ya que el régimen de catcode predeterminado lo incluye; presumiblemente, esto es para alentar a los escritores de paquetes a ocultar sus macros usando @-nombres cargados. Por esta razón, creo que usar esta El comando es inofensivo en los archivos del paquete.

Sin embargo, usando el par de comandos juntos es perjudicial, porque a diferencia de un documento, no no quiero volver a la @ = other configuración dentro del paquete. Estos son los comandos de documentos y los pedidos estándar. makeatletter makeatother asume que makeatother en realidad está deshaciendo el cambio anterior, mientras que en los paquetes, es el que realiza el cambio.

Editar: Aquí hay una respuesta más informada. De acuerdo a source2e.pdf, el siguiente esquema se utiliza para cargar paquetes y clases:

  1. Primero, se recopilan las opciones y demás.
  2. Luego, el nombre del archivo actual (es decir, mypackage.sty), junto con el catcode de @, se guardan en una pila.
  3. Luego makeatletter se ejecuta y, si procede, se carga el archivo solicitado.
  4. Posteriormente, se abre la pila y se restaura el estado de carga previa al paquete.

En otras palabras, el siguiente código ignorante tiene ningún efecto en absoluto:

documentclass{article}
usepackage{bad}
begin{document}
end{document}

bad.sty:

makeatletter
makeatother
RequirePackage{unsuspecting}

Sin embargo, es muy posible que un paquete no no usar RequirePackage, pero solo input. En ese caso, el catcode es no protegido y, de hecho, pueden surgir errores, ya que puede comprobarse a sí mismo haciendo bad.sty, por ejemplo:

makeatletter
makeatother
input{pgfkeys.sty}

Si eso parece artificial, eche un vistazo a pgfkeys.sty sí mismo: es inputs pgfkeys.code.tex, y ese archivo, a su vez, inputs pgfkeysfiltered.code.tex. Presumiblemente, el autor se sintió seguro una vez dentro de su propio paquete, ¡pero no sospechaba que alguien más podría eludir los mecanismos de protección de carga de paquetes también!

Esto fue mucho más serio en LaTeX2.09 ya que LaTeX acababa de ejecutarse makeatletter una vez antes de manejar todos los .sty archivos (LaTeX2.09 no dio el .cls/.sty distinción). Así que era un problema común, casi una pregunta frecuente, que se lanzaran paquetes que ejecutaban makeatother al final del archivo y trabajaron de forma aislada, pero rompieron los siguientes “archivos de estilo” (también conocidos como paquetes).

Así que una de las primeras cosas que se hizo para 2e fue restablecer el código de cat. De @ al cargar cada paquete, mantener una pila para que el código de cat se restaure al final del paquete a lo que era antes. Por lo tanto por diseño es difícil encontrar un ejemplo en el que un pícaro makeatother al final de un paquete hace daño.

Dicho esto, es mejor no caerse que confiar en una red de seguridad.

Siempre que esté consciente de no hacer cosas malas dentro de su propio paquete (como el ejemplo de Ryan Reich), parece estar seguro dentro de los límites de lo que ofrece LaTeX.

Pero todavía los peligros acechan a la vuelta de la esquina.

Si yo digo

usepackage{afterpackage}

AfterPackage{foo}{input{bar}}

usepackage{foo}

y dentro foo.sty

makeatother

y dentro bar.tex

[email protected]baz{quux}

entonces me sale un error porque @ no es una carta (lo cual no sucede sin el makeatother).

(el punto principal de esta respuesta es, por supuesto, que la persona (desprevenida) que usa AfterPackage no es necesariamente el mismo que el autor del paquete)

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *