Algunos compiladores (especialmente los de C o C ++) le dan advertencias sobre:
No new line at end of file
Pensé que esto sería un problema exclusivo de los programadores C, pero github muestra un mensaje en la vista de confirmación:
\ No newline at end of file
para un archivo PHP.
Entiendo lo del preprocesador explicado en este hilo , pero ¿qué tiene esto que ver con PHP? ¿Es lo mismo include()
o está relacionado con el tema \r\n
vs \n
?
¿Cuál es el punto de tener una nueva línea al final de un archivo?
cat
el archivo, el siguiente mensaje se agregará a la "línea" final si no termina con una nueva línea.Respuestas:
No se trata de agregar una nueva línea adicional al final de un archivo, se trata de no eliminar la nueva línea que debería estar allí.
Un archivo de texto , bajo unix, consta de una serie de líneas , cada una de las cuales termina con un carácter de nueva línea (
\n
). Por lo tanto, un archivo que no está vacío y no termina con una nueva línea no es un archivo de texto.Las utilidades que se supone que operan en archivos de texto pueden no funcionar bien con archivos que no terminan con una nueva línea; Las utilidades históricas de Unix pueden ignorar el texto después de la última línea nueva, por ejemplo. Las utilidades de GNU tienen una política de comportarse decentemente con archivos que no son de texto, al igual que la mayoría de las otras utilidades modernas, pero aún puede encontrar comportamientos extraños con los archivos a los que les falta una nueva línea final¹.
Con GNU diff, si uno de los archivos que se comparan termina con una nueva línea pero no con el otro, es importante tener en cuenta ese hecho. Dado que diff está orientado a líneas, no puede indicar esto almacenando una nueva línea para uno de los archivos, pero no para los demás; las nuevas líneas son necesarias para indicar dónde comienza y termina cada línea en el archivo diff . Así que diff usa este texto especial
\ No newline at end of file
para diferenciar un archivo que no terminó en una nueva línea de un archivo que sí lo hizo.Por cierto, en un contexto C, un archivo fuente de manera similar consiste en una serie de líneas. Más precisamente, una unidad de traducción se ve en una implementación definida como una serie de líneas, cada una de las cuales debe terminar con un carácter de nueva línea ( n1256 §5.1.1.1). En sistemas unix, el mapeo es sencillo. En DOS y Windows, cada secuencia CR LF (
\r\n
) se asigna a una nueva línea (\n
; esto es lo que siempre sucede cuando se lee un archivo abierto como texto en estos sistemas operativos). Existen algunos sistemas operativos que no tienen un carácter de nueva línea, sino que tienen registros de tamaño fijo o variable; En estos sistemas, la asignación de archivos a la fuente C introduce un\n
al final de cada registro. Si bien esto no es directamente relevante para Unix, significa que si copia un archivo fuente C que falta su nueva línea final en un sistema con archivos de texto basados en registros, luego cópielo de nuevo, o terminará con el archivo incompleto última línea truncada en la conversión inicial, o una nueva línea adicional añadida durante la conversión inversa.¹ Ejemplo: la salida del ordenamiento GNU siempre termina con una nueva línea. Entonces, si al archivo
foo
le falta su nueva línea final, encontrará quesort foo | wc -c
informa un carácter más quecat foo | wc -c
.fuente
No necesariamente la razón, sino una consecuencia práctica de los archivos que no terminan con una nueva línea:
Considere lo que sucedería si quisiera procesar varios archivos usando
cat
. Por ejemplo, si desea encontrar la palabrafoo
al comienzo de la línea en 3 archivos:Si la primera línea en el archivo 3 comienza con
foo
, pero el archivo 2 no tiene una final\n
después de su última línea, grep no encontrará esta ocurrencia, porque grep verá la última línea en el archivo 2 y la primera línea en el archivo 3 como un solo línea.Entonces, por consistencia y para evitar sorpresas, trato de mantener mis archivos siempre terminando con una nueva línea.
fuente
'\n'
en funcionamiento el gato ...\n
espacios en blanco en los extremos, por lo que para mantener las cosas coherentes, siempre pongo\n _____
ambos extremos de mis cadenas". Bueno, no, lo correcto es tener sus cadenas recortadas y luego concatenarlas adecuadamente.Hay dos aspectos:
Hay / hubo algunos compiladores de C que no pueden analizar la última línea si no termina con una nueva línea. El estándar C especifica que un archivo C debe terminar con una nueva línea (C11, 5.1.1.2, 2.) y que una última línea sin una nueva línea produce un comportamiento indefinido (C11, J.2, segundo elemento). Quizás por razones históricas, porque algún proveedor de tal compilador era parte del comité cuando se redactó el primer estándar. De ahí la advertencia de GCC.
diff
Los programas (como los utilizados porgit diff
Github, etc.) muestran diferencias línea por línea entre los archivos. Por lo general, imprimen un mensaje cuando solo un archivo termina con una nueva línea porque de lo contrario no vería esta diferencia. Por ejemplo, si la única diferencia entre dos archivos es la presencia del último carácter de nueva línea, sin la sugerencia, parecería que ambos archivos son iguales, cuandodiff
ycmp
devuelve un código de salida de éxito desigual y las sumas de comprobación de los archivos (por ejemplo, a través demd5sum
) no coinciden.fuente
diff
se espera que imprima las diferencias si hay alguna. Y si un archivo tiene una nueva línea como último carácter mientras que el otro no, entonces esa diferencia debe ser notable de alguna manera en la salida.\n
) para empezar, sino que simplemente puede mostrar "nuevas líneas".Lo
\ No newline at end of file
que obtiene de github aparece al final de un parche (endiff
formato , vea la nota al final de la sección "Formato unificado").A los compiladores no les importa si hay una nueva línea o no al final de un archivo, pero
git
(y lasdiff
/patch
utilidades) deben tenerlas en cuenta. Hay muchas razones para eso. Por ejemplo, olvidar agregar o quitar una nueva línea al final de un archivo cambiaría su hashsum (md5sum
/sha1sum
). Además, los archivos no siempre son programas, y un final\n
puede hacer alguna diferencia.Nota : sobre la advertencia de los compiladores de C, supongo que insisten en una nueva línea final para fines de compatibilidad con versiones anteriores. Los compiladores muy antiguos podrían no aceptar la última línea si no termina con
\n
(u otra secuencia de caracteres de fin de línea dependiente del sistema).fuente
También existe el punto de mantener la historia diferencial. Si un archivo finaliza sin un carácter de nueva línea, las utilidades diff verán que agregar cualquier cosa al final del archivo cambiará esa última línea (porque
\n
se le está agregando).Esto podría causar resultados no deseados con comandos como
git blame
yhg annotate
.fuente
-w
opción para ignorar los cambios en los espacios en blanco al generar datos para humanos.POSIX, este es un conjunto de estándares especificados por IEEE para mantener la compatibilidad entre sistemas operativos.
Una de ellas es la definición de una "línea" que es una secuencia de cero o más no caracteres más un carácter de nueva línea de terminación.
Por lo tanto, para que esa última línea se reconozca como una "línea" real, debe tener un nuevo carácter de línea de terminación.
Esto es importante si depende de las herramientas del sistema operativo para decir el recuento de líneas o dividir / ayudar a analizar su archivo. Dado que PHP es un lenguaje de script, es completamente posible, especialmente en sus primeros días o incluso ahora (no tengo idea / postulación) tenía dependencias del sistema operativo como ese.
En realidad, la mayoría de los sistemas operativos no son totalmente compatibles con POSIX y a los humanos no les gusta esa máquina o ni siquiera se preocupan por terminar nuevas líneas. Entonces, para la mayoría de las cosas, es una mezcla heterogénea de todo, ya sea que se preocupe por eso, advierta o simplemente que ir al último fragmento de texto sea realmente una línea, así que simplemente inclúyalo.
fuente