CONTENIDO

  • NOMBRE
  • DESCRIPCIÓN
    • Campos de texto
    • Campos numéricos
    • El campo @ * para texto multilínea de ancho variable
    • El campo ^ * para texto de una línea de ancho variable a la vez
    • Especificando valores
    • Usando el modo de relleno
    • Suprimir líneas donde todos los campos están vacíos
    • Líneas de formato repetidas
    • Procesamiento de la parte superior del formulario
    • Variables de formato
  • NOTAS
    • Pies de página
    • Acceso a los componentes internos de formateo
  • ADVERTENCIAS

NOMBRE

perlform – formatos Perl

DESCRIPCIÓN

Perl tiene un mecanismo para ayudarlo a generar informes y gráficos simples. Para facilitar esto, Perl lo ayuda a codificar su página de salida de manera similar a cómo se verá cuando se imprima. Puede realizar un seguimiento de cosas como cuántas líneas hay en una página, en qué página se encuentra, cuándo imprimir encabezados de página, etc. Las palabras clave se toman prestadas de FORTRAN: formato () para declarar y escribir () para ejecutar; ver sus entradas en perlfunc. Afortunadamente, el diseño es mucho más legible, más parecido a la declaración PRINT USING de BASIC. Piense en ello como el nroff de un pobre (1).

Los formatos, como paquetes y subrutinas, se declaran en lugar de ejecutarse, por lo que pueden ocurrir en cualquier punto de su programa. (Aunque normalmente es mejor mantenerlos todos juntos). Tienen su propio espacio de nombres aparte de todos los demás “tipos” en Perl. Esto significa que si tiene una función llamada “Foo”, no es lo mismo que tener un formato llamado “Foo”. Sin embargo, el nombre predeterminado para el formato asociado con un identificador de archivo determinado es el mismo que el nombre del identificador de archivo. Por lo tanto, el formato predeterminado para STDOUT se denomina “STDOUT” y el formato predeterminado para el identificador de archivos TEMP se denomina “TEMP”. Simplemente se ven iguales. No lo son.

Los formatos de registro de salida se declaran de la siguiente manera:

format NAME =
FORMLIST
.

Si se omite el nombre, se define el formato “STDOUT”. Un solo “.” en la columna 1 se utiliza para terminar un formato. FORMLIST consta de una secuencia de líneas, cada una de las cuales puede ser de tres tipos:

  1. Un comentario, indicado poniendo un ‘#’ en la primera columna.

  2. Una línea de “imagen” que da el formato de una línea de salida.

  3. Una línea de argumento que proporciona valores para conectar con la línea de imagen anterior.

Las líneas de imagen contienen definiciones de campo de salida, entremezcladas con texto literal. Estas líneas no sufren ningún tipo de interpolación variable. Las definiciones de campo se componen de un conjunto de caracteres, para iniciar y extender un campo a su ancho deseado. Este es el conjunto completo de caracteres para las definiciones de campo:

@    start of regular field
^    start of special field
<    pad character for left justification
|    pad character for centering
>    pad character for right justification
#    pad character for a right-justified numeric field0    instead of first #: pad number with leading zeroes.    decimal point within a numeric field
...  terminate a text field, show "..." as truncation evidence
@*   variable width field for a multi-line value
^*   variable width field fornext line of a multi-line value
~    suppress line with all fields empty
~~   repeat line until all fields are exhausted

Cada campo en una línea de imagen comienza con “@” (arroba) o “^” (signo de intercalación), lo que indica lo que llamaremos, respectivamente, un campo “regular” o “especial”. La elección de los caracteres del pad determina si un campo es textual o numérico. Los operadores de tilde no forman parte de un campo. Veamos las diversas posibilidades en detalle.

Campos de texto

La longitud del campo se proporciona rellenando el campo con varios “<", ">“, o” | “para especificar un campo no numérico con, respectivamente, justificación a la izquierda, justificación a la derecha o centrado. Para un campo normal, el valor (hasta la primera línea nueva) se toma y se imprime de acuerdo con la justificación seleccionada , truncando el exceso de caracteres. Si termina un campo de texto con “…”, se mostrarán tres puntos si el valor está truncado. Se puede utilizar un campo de texto especial para realizar un relleno rudimentario de bloques de texto de varias líneas; consulte “Uso de Rellenar Mode “para obtener más detalles.

Example:
   format STDOUT =@<<<<<<@||||||@>>>>>>"left","middle","right".
Output:
   left      middle    right

Campos numéricos

El uso de “#” como carácter de relleno especifica un campo numérico, con justificación a la derecha. Un “.” Opcional define la posición del punto decimal. Con un “0” (cero) en lugar del primer “#”, el número formateado se rellenará con ceros a la izquierda si es necesario. Un campo numérico especial se borra si el valor no está definido. Si el valor resultante supera el ancho especificado, el campo se rellena con “#” como evidencia de desbordamiento.

Example:
   format STDOUT =
   @###   @.###   @##.###  @###   @###   ^####42,3.1415,undef,0,10000,undef.
Output:423.1420.0000####

El campo @ * para texto multilínea de ancho variable

El campo “@ *” se puede utilizar para imprimir valores no truncados de varias líneas; debería (pero no es necesario) aparecer por sí mismo en una línea. Se muerde un avance de línea final, pero todos los demás caracteres se emiten literalmente.

El campo ^ * para texto de una línea de ancho variable a la vez

Como “@ *”, este es un campo de ancho variable. El valor proporcionado debe ser una variable escalar. Perl coloca la primera línea (hasta la primera ” n”) del texto en el campo y luego corta el frente de la cadena para que la próxima vez que se haga referencia a la variable, se pueda imprimir más texto. La variable no ser restaurado.

Example:$text="line 1nline 2nline 3";
   format STDOUT =
   Text:^*$text~~^*$text.
Output:
   Text: line 1
         line 2
         line 3

Especificando valores

Los valores se especifican en la siguiente línea de formato en el mismo orden que los campos de imagen. Las expresiones que proporcionan los valores deben estar separadas por comas. Todos se evalúan en un contexto de lista antes de que se procese la línea, por lo que una sola expresión de lista podría producir varios elementos de lista. Las expresiones pueden extenderse a más de una línea si están entre llaves. Si es así, la llave de apertura debe ser la primera ficha en la primera línea. Si una expresión se evalúa como un número con una parte decimal, y si la imagen correspondiente especifica que la parte decimal debe aparecer en la salida (es decir, cualquier imagen excepto varios caracteres “#” sin un “.” incrustado), el carácter utilizado para el punto decimal está determinado por la configuración regional LC_NUMERIC actual si use locale está en efecto. Esto significa que, si, por ejemplo, el entorno de tiempo de ejecución especifica una configuración regional alemana, se utilizará “,” en lugar del “.” Predeterminado. Consulte perllocale y “ADVERTENCIAS” para obtener más información.

Usando el modo de relleno

En los campos de texto, el símbolo de intercalación habilita una especie de modo de relleno. En lugar de una expresión arbitraria, el valor proporcionado debe ser una variable escalar que contenga una cadena de texto. Perl coloca la siguiente parte del texto en el campo y luego corta el frente de la cadena para que la próxima vez que se haga referencia a la variable, se pueda imprimir más texto. (Sí, esto significa que la propia variable se modifica durante la ejecución de la llamada write () y no se restaura). La siguiente parte del texto se determina mediante un algoritmo de salto de línea crudo. Puede utilizar el carácter de retorno de carro (r) para forzar un salto de línea. Puede cambiar qué caracteres son legales para romper cambiando la variable $: (eso es $ FORMAT_LINE_BREAK_CHARACTERS si está utilizando el módulo de inglés) a una lista de los caracteres deseados.

Normalmente, usaría una secuencia de campos en una pila vertical asociada con la misma variable escalar para imprimir un bloque de texto. Es posible que desee terminar el campo final con el texto “…”, que aparecerá en la salida si el texto es demasiado largo para aparecer en su totalidad.

Suprimir líneas donde todos los campos están vacíos

El uso de campos de intercalación puede producir líneas en las que todos los campos están en blanco. Puede suprimir estas líneas colocando un carácter “~” (tilde) en cualquier lugar de la línea. La tilde se traducirá a un espacio en la salida.

Líneas de formato repetidas

Si coloca dos caracteres de tilde contiguos “~~” en cualquier lugar de una línea, la línea se repetirá hasta que se agoten todos los campos de la línea, es decir, sin definir. En el caso de campos de texto especiales (intercalación), esto ocurrirá tarde o temprano, pero si usa un campo de texto de la variedad at, es mejor que la expresión que proporcione no dé el mismo valor siempre para siempre. (shift(@f) es un ejemplo simple que funcionaría. No use un campo numérico regular (arroba) en tales líneas, porque nunca quedará en blanco.

Procesamiento de la parte superior del formulario

El procesamiento de inicio de formulario se gestiona de forma predeterminada mediante un formato con el mismo nombre que el identificador de archivo actual con “_TOP” concatenado. Se activa en la parte superior de cada página. Consulte “escribir” en perlfunc.

Ejemplos:

# a report on the /etc/passwd file
format STDOUT_TOP =
                        Passwd File
Name                Login    Office   Uid   Gid Home
------------------------------------------------------------------.
format STDOUT =@<<<<<<<<<<<<<<<<<<@|||||||@<<<<<<@>>>>@>>>>@<<<<<<<<<<<<<<<<<$name,$login,$office,$uid,$gid,$home.# a report from a bug report form
format STDOUT_TOP =
                        Bug Reports
@<<<<<<<<<<<<<<<<<<<<<<<@|||@>>>>>>>>>>>>>>>>>>>>>>>$system,$%,$date------------------------------------------------------------------.
format STDOUT =
Subject:@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<$subject
Index:@<<<<<<<<<<<<<<<<<<<<<<<<<<<<^<<<<<<<<<<<<<<<<<<<<<<<<<<<<$index,$description
Priority:@<<<<<<<<<< Date:@<<<<<<<^<<<<<<<<<<<<<<<<<<<<<<<<<<<<$priority,$date,$description
From:@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<^<<<<<<<<<<<<<<<<<<<<<<<<<<<<$from,$description
Assigned to:@<<<<<<<<<<<<<<<<<<<<<<^<<<<<<<<<<<<<<<<<<<<<<<<<<<<$programmer,$description~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<$description~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<$description~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<$description~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<$description~^<<<<<<<<<<<<<<<<<<<<<<<...$description.

Es posible entremezclar print () s con write () s en el mismo canal de salida, pero tendrás que manejar $- ($FORMAT_LINES_LEFT) tú mismo.

Variables de formato

El nombre del formato actual se almacena en la variable $~ ($FORMAT_NAME), y el nombre del formato de inicio de formulario actual está en $^ ($FORMAT_TOP_NAME). El número de página de salida actual se almacena en $% ($FORMAT_PAGE_NUMBER), y el número de líneas de la página está en $= ($FORMAT_LINES_PER_PAGE). Si la salida de autoflujo en esta manija se almacena en $| ($OUTPUT_AUTOFLUSH). La salida de la cadena antes de cada parte superior de la página (excepto la primera) se almacena en $^L ($FORMAT_FORMFEED). Estas variables se configuran por manejo de archivo, por lo que deberá seleccionar () en una diferente para afectarlas:

select((select(OUTF),$~="My_Other_Format",$^="My_Top_Format")[0]);

Bastante feo, ¿eh? Sin embargo, es un modismo común, así que no se sorprenda demasiado cuando lo vea. Puede al menos usar una variable temporal para mantener el identificador de archivo anterior: (este es un enfoque mucho mejor en general, porque no solo mejora la legibilidad, ahora tiene una etapa intermedia en la expresión para realizar un solo paso del depurador):

$ofh= select(OUTF);$~="My_Other_Format";$^="My_Top_Format";
select($ofh);

Si usa el módulo en inglés, incluso puede leer los nombres de las variables:

use English;$ofh= select(OUTF);$FORMAT_NAME="My_Other_Format";$FORMAT_TOP_NAME="My_Top_Format";
select($ofh);

Pero todavía tienes esas selecciones divertidas. Así que solo usa el módulo FileHandle. Ahora, puede acceder a estas variables especiales usando nombres de métodos en minúsculas en su lugar:

use FileHandle;
format_name     OUTF "My_Other_Format";
format_top_name OUTF "My_Top_Format";

¡Mucho mejor!

NOTAS

Debido a que la línea de valores puede contener expresiones arbitrarias (para campos at, no campos de intercalación), puede dedicar un procesamiento más sofisticado a otras funciones, como sprintf () o una de las suyas. Por ejemplo:

format Ident =@<<<<<<<<<<<<<<<&commify($n).

Para obtener una at real o un intercalador en el campo, haga lo siguiente:

format Ident =
I have an @ here."@".

Para centrar una línea completa de texto, haga algo como esto:

format Ident =@|||||||||||||||||||||||||||||||||||||||||||||||"Some text line".

No hay una forma incorporada de decir “flotar esto hacia el lado derecho de la página, por muy ancha que sea”. Tienes que especificar a dónde va. Los verdaderamente desesperados pueden generar su propio formato sobre la marcha, en función del número actual de columnas, y luego evaluarlo ():

$format="format STDOUT = n".'^'.'<'x$cols."n".'$entry'."n"."t^"."<"x($cols-8)."~~n".'$entry'."n".".n";print$formatif$Debugging;eval$format;die[email protected]if[email protected];

Lo que generaría un formato parecido a esto:

format STDOUT =^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<$entry^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~$entry.

Aquí hay un pequeño programa que es algo así como fmt (1):

format =^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~$_.$/='';while(<>)s/s*ns*/ /g;
    write;

Pies de página

Si bien $ FORMAT_TOP_NAME contiene el nombre del formato de encabezado actual, no existe un mecanismo correspondiente para hacer lo mismo automáticamente para un pie de página. No saber qué tan grande será un formato hasta que lo evalúes es uno de los principales problemas. Está en la lista de TODO.

Aquí hay una estrategia: si tiene un pie de página de tamaño fijo, puede obtener pies de página marcando $ FORMAT_LINES_LEFT antes de cada escritura () e imprima el pie de página usted mismo si es necesario.

Aquí hay otra estrategia: abre una tubería para ti mismo, usando open(MYSELF, "|-") (ver “abrir” en perlfunc) y siempre escribo () en MI MISMO en lugar de STDOUT. Haga que su hijo procese su STDIN para reorganizar los encabezados y pies de página como desee. No muy conveniente, pero factible.

Acceso a los componentes internos de formateo

Para acceso de bajo nivel al mecanismo de formato, puede usar formline () y acceder $^A (la variable $ ACCUMULATOR) directamente.

Por ejemplo:

$str= formline <<'END',1,2,3;@<<<@|||@>>>
END

print"Wow, I just stored '$^A' in the accumulator!n";

O para hacer una subrutina swrite (), que es escribir () lo que sprintf () es printf (), haga esto:

use Carp;sub swrite
       croak "usage: swrite PICTURE ARGS"unless@_;my$format= shift;$^A="";
       formline($format,@_);return$^A;$string= swrite(<<'END',1,2,3);
Check me out
@<<<@|||@>>>
END
   print$string;

ADVERTENCIAS

El único punto que termina un formato también puede terminar prematuramente un mensaje de correo que pasa a través de un mailer de Internet mal configurado (y según la experiencia, tal configuración incorrecta es la regla, no la excepción). Por lo tanto, cuando envíe un código de formato por correo, debe aplicar una sangría para que el punto de finalización del formato no esté en el margen izquierdo; esto evitará el corte de SMTP.

Las variables léxicas (declaradas con “mi”) no son visibles dentro de un formato a menos que el formato se declare dentro del alcance de la variable léxica.

Si el entorno de un programa especifica una configuración regional LC_NUMERIC y use locale está en vigor cuando se declara el formato, la configuración regional se utiliza para especificar el carácter de punto decimal en la salida formateada. La salida formateada no puede ser controlada por use locale en el momento en que se llama a write (). Consulte perllocale para obtener más información sobre el manejo de configuraciones regionales.

Dentro de las cadenas que se mostrarán en un campo de texto de longitud fija, cada carácter de control se sustituye por un espacio. (Pero recuerda el significado especial de r cuando se usa el modo de relleno). Esto se hace para evitar la desalineación cuando los caracteres de control “desaparecen” en algunos medios de salida.