2012-06-21 46 views
6

Normalmente miro ghostscript como una herramienta de línea de comandos; sin embargo, nunca dejo de sorprenderme por la gran cantidad de configuraciones y opciones presentes, que se debe al hecho de que ghostscript es un intérprete de lenguaje PostScript completo (que a menudo olvido).¿Qué son los diccionarios PostScript, y cómo se puede acceder (a través de Ghostscript)?

Por ejemplo, en Querying Ghostscript for the default options/settings of an output device (such as 'pdfwrite' or 'tiffg4'); uno aprende a recuperar las opciones predeterminadas para un dispositivo de salida determinado. Sin embargo, lo que me gustaría saber es si estas opciones están relacionadas con los llamados diccionarios PostScript.

O, para decirlo en otras palabras, ¿qué son los diccionarios PostScript; y qué facilidades tiene ghostscript, para consultar (y posiblemente) modificar estos datos?

Respuesta

8

Para ponerlo en los términos más simples: En PostScript, un diccionario es una lista de clave (nombre) + valor pares. Los diccionarios permiten al intérprete PostScript buscar si existe una clave y recuperar su valor para usarla en cualquier procedimiento. El intérprete también puede crear claves, almacenar o modificar valores e incluso crear diccionarios personalizados completos (dictados por el código PostScript de su procesamiento). Las claves usualmente son de tipo nombre (pero también pueden ser de cualquier otro tipo con la excepción de nulo).

Dos de estos diccionarios debe estar siempre presente, por cualquier implementación de un intérprete de PostScript:

  • systemdict Éste tiene predefinido operadores PostScript (y las implementaciones de hacer que hagan lo que el La especificación PostScript los espera).

  • userdict Éste tiene variables y procedimientos de un programa PostScript (pensar en 'procedimientos' como funciones o subrutinas que se construyen mediante la combinación de los operadores de idioma definido y los valores definidos por el programa y parámetros).

Una palabra sobre nombres: los nombres son lo que a otros lenguajes de programación son uniq identificadores (y son mayúsculas y minúsculas). Estos identificadores pueden ser variables o nombres de procedimientos.Pueden estar formados por cualquier combinación de los 256 caracteres de ASCII (pero no son strings).

Como ya sabrá, PostScript es un stack -oriented language. Se utiliza varias pilas:

  • pila de operandos Esta pila tiene cada operando y cada resultado de las operaciones intermedias (girando el último resultado temporalmente en el elemento de la parte superior la mayor parte de la pila de operandos).

  • pila de diccionario Como su nombre es: esta pila solo contiene diccionarios. Como tal, la pila define el contexto actual para cualquier búsqueda de clave/nombre.

  • pila de ejecución Esta uno sostiene ejecutables objetos, es decir, principalmente procedimientos y archivos que se están ejecutando en ese momento. Si el intérprete interrumpe la ejecución de un objeto actual, coloca el objeto interrumpido en esta pila. Después de que un objeto se ejecutó por completo, se elimina de la pila y la ejecución continúa con la que está en primer lugar ahora.

  • gráficos pila estado Esta pila alberga el contexto actual de la expulsión de los elementos gráficos: configuración de ancho de línea actual, fuente actual, color actual o el valor de escala de grises, camino de la corriente ... estados gráficos actuales se salven (gsave) y restaurado (grestore) más adelante. El estado de gráficos más alto es siempre el estado de gráficos actuales .

Todas estas pilas son independientes entre sí. Sin embargo, las pilas de estado del operando, el diccionario y los gráficos están bajo el control del programa PostScript (es decir, pueden ser manipulados por él). La pila de ejecución es propiedad exclusiva del intérprete.

Para cada pila hay ciertas limitaciones (en cuanto a la cantidad de elementos que pueden almacenarse en ella, etc.). PostScript sabe operadores que pueden manipular pilas: poner un nuevo elemento en la pila, retire el más alto de elementos (pop), duplicar el más alto de elementos (dup), cambiar el orden de los elementos en la pila (roll), intercambie los dos elementos top-moste (exch), y bastante más (una buena introducción a la programación PostScript es 'Bluebook' de Adobe).

Como ya he dicho, los diccionarios tienen su propia pila que contiene todos los diccionarios que un intérprete de PostScript puede usar.

En esa pila puede haber un diccionario de fuentes, o cualquier número de diccionarios de un programa PostScript quiere crear (utilizando el dict palabra clave) y utilizar de forma privada, o algunos diccionarios que son específicos de un determinado intérprete de PostScript , como Ghostscript.

La systemdict siempre es la más inferior; encima de esto está el userdict. Estos dos no se pueden eliminar de la pila de diccionarios, mientras que los demás pueden estar sujetos a cualquier operador de manipulación de pila (como pop que elimina el elemento superior de una pila).

Cuando el intérprete busca un nombre, busca los diccionarios para ese nombre, comenzando por el diccionario más alto. Por lo tanto, userdict se busca antes de systemdict. Tan pronto como se encuentra el nombre (una clave), el intérprete deja de buscar y usa esa clave (o más bien, el valor que contiene). La consecuencia de esta arquitectura es que el programador PostScript puede sobrescribir cualquier operador PostScript que esté predefinido en systemdict con su propia variante.

Además, algunos diccionarios pueden ser para el programa PS 'privado' (sin acceso, como diccionarios de fuentes) o 'de solo lectura'.


actualización - Más respuestas:

+0

Muchas gracias por la respuesta detallada, @pipitas! Si/cuando tienes tiempo, también podrías agregar un breve ejemplo de terminal 'ghostscript', de" _ el intérprete [] buscando un nombre_ "(que también puede mostrar que '_'userdict' se busca antes de' systemdict'_, y posiblemente sobrescribir a un operador)? Muchas gracias de nuevo, ¡salud! – sdaau

+1

@sdaau: mi otra respuesta muestra cómo buscar el nombre/tecla '/ pantalla' en el diccionario' .distillersettings': es tan simple como '.distillersettings/screen get'. El operador 'get' pone el valor de la clave (si se encuentra) en la pila del operando (si no se encuentra, se imprimirá un error' undefined'). Ahora que el valor de la clave está en la pila, el resto del fragmento de código simplemente lo trae allí, lo formatea un poco para que se vea mejor e imprime su contenido ... –

+0

Muchas gracias, @pipitas: ¡muy apreciado! – sdaau

2

Los diccionarios en PostScript son un objeto 'contenedor', son en esencia una lista de pares, una clave y un valor. Consulte el Manual de referencia del lenguaje PostScript para obtener más detalles, especialmente la sección 3.3.9 en la tercera edición.

Los diccionarios se utilizan a menudo para pasar un conjunto de parámetros a un operador o función PostScript, por ejemplo, el operador de imágenes puede tomar un argumento de diccionario, pero también puede ser simplemente de almacenamiento.

Los diccionarios pueden tener permisos de acceso, por lo que es posible tener diccionarios de solo lectura, cuyos valores pueden examinarse, pero no modificarse, y los diccionarios de fuentes pueden ser "sin acceso" para evitar que los datos de contorno se extraigan en PostScript.

Las entradas en un diccionario que no sea de solo lectura o de no acceso se pueden modificar a voluntad.

+0

Muchas gracias por la respuesta, @KenS; aquí también hay un enlace al actual [Manual de referencia del lenguaje PostScript (PLRM.pdf)] (http://www.adobe.com/products/postscript/pdfs/PLRM.pdf) - ¡Salud! – sdaau

5

Las otras respuestas ya cubrió el "¿Cuáles son los diccionarios?" parte de su pregunta. Ahora veamos el "¿Cómo puede Ghostscript acceder a ellos?"

Quizás la pregunta debería ser más bien: "¿Cómo puedo (un usuario avanzado, un desarrollador, un geek ...) acceder a ellos?"

Puede imprimir el contenido de cualquier diccionario accesible que sea conocido para su intérprete PostScript (que puede ser Ghostscript) escribiendo un programa simple PostScript one-liner o simplemente llamando al intérprete (Ghostscript) con el programa código entregado en la línea de comandos (-c ...).

Solo necesita saber el nombre del diccionario respectivo para esto.

Veamos uno de esos diccionario Ghostscript interna interesante, llamado .distillersettings:

gs \ 
-dNODISPLAY \ 
-c ".distillersettings {exch ==only () print ==} forall quit" 

Resultado:

/default -dict- 
/prepress -dict- 
/PSL2Printer -dict- 
/ebook -dict- 
/screen -dict- 
/printer -dict- 

Esto no se puede decir mucho a primera vista. Pero puede reconocer algunos de los nombres clave en ese diccionario: /prepress, /printer, /screen, /ebook ...

Todos estos se pueden utilizar en una línea de comandos de Ghostscript para solicitar un conjunto predefinido de configuraciones cuando se desea un resultado creado por -sDEVICE=pdfwrite (la funcionalidad Ghostscript 'Distiller'-similar). Para solicitar dicho conjunto de configuraciones, simplemente agregue -dPDFSETTINGS=/printer a la línea de comandos.

En la segunda mirada ahora verá que el contenido del diccionario .distillersettings es esencialmente un conjunto de 6 diccionarios más. Es un 'diccionario de diccionarios'.

Los contenidos del diccionario no se imprimen por defecto (no con el código PostScript anterior). Pero si los quiere, puede usar un procedimiento específico de Ghostscript llamado === en lugar del operador estándar de lenguaje PostScript == en el comando anterior. Este procedimiento se comporta de la misma manera que == execpt que también expande los diccionarios e imprime todos los pares clave: valor contenidos en ellos.

tener cuidado con ese procedimiento ===: la -dict- que está tratando de ampliar puede ser veeeeeery largo y podría hacer que se pierda la vista. :-)

En nuestro caso actual sin embargo, todavía es manejable:

gs \ 
-dNODISPLAY \ 
-c ".distillersettings {exch ==only () print ===} forall quit" 

salida actual es:

/default << /Optimize false /DoThumbnails false /PreserveEPSInfo true /ColorConversionStrategy /LeaveColorUnchanged /DownsampleMonoImages false /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments true /GrayACSImageDict << /HSamples [2 1 1 2] /VSamples [2 1 1 2] /QFactor 0.9 /Blend 1 >> /DownsampleColorImages false /PreserveOverprintSettings true /CreateJobTicket false /AutoRotatePages /PageByPage /NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] /ColorACSImageDict << /HSamples [2 1 1 2] /VSamples [2 1 1 2] /QFactor 0.9 /Blend 1 >> /DownsampleGrayImages false /UCRandBGInfo /Preserve >> 
/prepress << /DoThumbnails true /MonoImageResolution 1200 /ColorImageDownsampleType /Bicubic /PreserveEPSInfo true /ColorConversionStrategy /LeaveColorUnchanged /GrayImageDownsampleType /Bicubic /EmbedAllFonts true /CannotEmbedFontPolicy /Error /PreserveOPIComments true /GrayImageResolution 300 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /ColorImageResolution 300 /PreserveOverprintSettings true /CreateJobTicket true /AutoRotatePages /None /MonoImageDownsampleType /Bicubic /NeverEmbed [] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /CompatibilityLevel 1.4 /UCRandBGInfo /Preserve >> 
/PSL2Printer << /DoThumbnails false /CompatibilityLevel 1.2 /TransferFunctionInfo /Preserve /MonoImageResolution 1200 /PreserveEPSInfo true /CompressFonts true /ColorImageDownsampleType /Bicubic /GrayImageDownsampleType /Bicubic /ColorConversionStrategy /LeaveColorUnchanged /EmbedAllFonts true /ColorACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /CannotEmbedFontPolicy /Error /PreserveOPIComments true /CompressPages true /GrayImageResolution 600 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /ColorImageResolution 600 /PreserveOverprintSettings true /AutoRotatePages /None /MonoImageDownsampleType /Bicubic /ASCII85EncodePages true /MaxViewerMemorySize 8000000 /NeverEmbed [] /PreserveHalftoneInfo true /UCRandBGInfo /Preserve >> 
/ebook << /DoThumbnails false /MonoImageResolution 300 /ColorImageDownsampleType /Bicubic /PreserveEPSInfo false /ColorConversionStrategy /sRGB /GrayImageDownsampleType /Bicubic /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments false /GrayImageResolution 150 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /ColorImageResolution 150 /PreserveOverprintSettings false /CreateJobTicket false /AutoRotatePages /All /MonoImageDownsampleType /Bicubic /NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /CompatibilityLevel 1.4 /UCRandBGInfo /Remove >> 
/screen << /DoThumbnails false /MonoImageResolution 300 /ColorImageDownsampleType /Average /PreserveEPSInfo false /ColorConversionStrategy /sRGB /GrayImageDownsampleType /Average /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments false /GrayImageResolution 72 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /ColorImageResolution 72 /PreserveOverprintSettings false /CreateJobTicket false /AutoRotatePages /PageByPage /MonoImageDownsampleType /Average /NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /CompatibilityLevel 1.3 /UCRandBGInfo /Remove >> 
/printer << /DoThumbnails false /MonoImageResolution 1200 /ColorImageDownsampleType /Bicubic /PreserveEPSInfo true /ColorConversionStrategy /UseDeviceIndependentColor /GrayImageDownsampleType /Bicubic /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments true /GrayImageResolution 300 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.4 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /ColorImageResolution 300 /PreserveOverprintSettings true /CreateJobTicket true /AutoRotatePages /None /MonoImageDownsampleType /Bicubic /NeverEmbed [] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.4 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /CompatibilityLevel 1.4 /UCRandBGInfo /Preserve >> 

Aún no tan agradable. Así que intentemos mejorarlo. La forma en que podemos hacerlo es modificar nuestro código PostScript: ahora le decimos que acceda al diccionario .distillersettings y obtenga el valor de una de las claves (use /screen). Como sabemos que el valor es otro diccionario, sabemos que vamos a llegar otro conjunto de pares clave: valor que vamos a ser capaces de formatear la misma manera que hicimos antes:

gs \ 
-q \ 
-dNODISPLAY \ 
-c ".distillersettings /screen get {exch ==only () print ===} forall quit" 

Ahora bien, esto se ve mejor, DOESN no es así? Véase a sí mismo:

/DoThumbnails false 
/MonoImageResolution 300 
/ColorImageDownsampleType /Average 
/PreserveEPSInfo false 
/ColorConversionStrategy /sRGB 
/GrayImageDownsampleType /Average 
/EmbedAllFonts true 
/CannotEmbedFontPolicy /Warning 
/PreserveOPIComments false 
/GrayImageResolution 72 
/GrayACSImageDict -dict- 
/ColorImageResolution 72 
/PreserveOverprintSettings false 
/CreateJobTicket false 
/AutoRotatePages /PageByPage 
/MonoImageDownsampleType /Average 
/NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica  /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] 
/ColorACSImageDict -dict- 
/CompatibilityLevel 1.3 
/UCRandBGInfo /Remove 

medida que su ojo agudo puede haber visto ya: algunos de los valores clave son de nuevo los diccionarios . Usted es libre de utilizar el comando de arriba de nuevo, esta vez con un === en lugar de la segunda == para resolver los misterios que /GrayACSImageDict -dict- y similares se pueden mantener escondite ...

En cualquier caso, ahora que sabes lo que ahorra en tecleando simplemente usando -dPDFSETTINGS=/screen en lugar de enumerar todos los parámetros individuales integrados en este diccionario /screen ...

Y también se sabe qué valor único que necesita para anular el caso de que desee de salida general de la calidad de 'pantalla', pero con la diferencia de que todas las fuentes se incrustan:

gs \ 
-o out.pdf \ 
-sDEVICE=pdfwrite \ 
-dPDFSETTINGS=/screen \ 
-c "<</NeverEmbed [ ] /AlwaysEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats]>> setdistillerparams" \ 
-f input.pdf 

Puedes explorar un montón de cosas interesantes de esta manera sobre las partes internas de Ghostscript, si solo conoces el nombre de los diccionarios que utiliza.:-)

+0

Fantástico, @pipitas - ahora ** esto ** es algo que he querido saber por bastante tiempo; especialmente lo que '==' significa, y cómo usarlo; la advertencia sobre diccionarios largos también se agradece, bueno, ¡todo el post es! Título editado, y si pudieras simplemente vincular esta respuesta al final de la aceptada, ¡sería genial! Muchas, muchas gracias por esto, ¡salud! – sdaau

4

Si desea obtener una lista de otros diccionarios que están contenidos en los systemdict y userdict diccionarios, basta con ejecutar:

for _dict in userdict systemdict; \ 
    do \ 
    gs \ 
    -dNODISPLAY \ 
    -c "${_dict} {exch ==only () print ==} forall quit"; \ 
done \ 
| awk '{print $1, $2}' \ 
| grep -- -dict- \ 
| sort 

Esto producirá una lista ordenada de nombres de diccionario que podrías investigar para nombres potencialmente 'interesantes'.

Encontrará tales nombres como Fontmap, localdict, AdobeGlyphList, userparams, .eexec_param_dict, .substitutefamilies, EncodingDirectory, colorspacedict, .distillerparamkeys, devicedict, .symbol_list, ...

Con cada uno de estos nombres se puede consultar más o menos interesante información y curiosidades sobre el funcionamiento interno de Ghostscript ejecutando Fe:

gs \ 
    -q \ 
    -dNODISPLAY \ 
    -c "Fontmap {exch ==only () print ==} forall quit" 

Como se puede ver, incluso el Fontmap utilizado por Ghostscript se almacena en un diccionario. Un extracto de mis resultados aquí es localmente esto:

[....] 
/Arial [/ArialMT] 
/Arial,Bold [/Arial-BoldMT] 
/AvantGarde-Book [/URWGothicL-Book] 
/Bookman-Demi [/URWBookmanL-DemiBold] 
/Calligraphic-Hiragana [(fhirw.gsf)] 
/Calligraphic-Katakana [(fkarw.gsf)] 
/Charter-Bold [/CharterBT-Bold] 
/CharterBT-Bold [(bchb.pfa)] 
/Courier [/NimbusMonL-Regu] 
/Courier-Bold [/NimbusMonL-Bold] 
/Courier-BoldOblique [/NimbusMonL-BoldObli] 
/Courier-Oblique [/NimbusMonL-ReguObli] 
/Helvetica [/NimbusSanL-Regu] 
/Helvetica-Bold [/NimbusSanL-Bold] 
/NewCenturySchlbk-Bold [/CenturySchL-Bold] 
/Palatino-Roman [/URWPalladioL-Roma] 
/Symbol [/StandardSymL] 
/Times-Bold [/NimbusRomNo9L-Medi] 
/TimesNewRoman,Bold [/TimesNewRomanPS-BoldMT] 
/Utopia-Regular [(putr.pfa)] 
/ZapfDingbats [/Dingbats] 
[....] 

nota de precaución: Lo anterior no es en realidad el formato de archivo que usted tiene que utilizar cuando se quiere manipular el Fontmap archivo que Ghostscript debería usar (en general, o para un trabajo en particular). Para ese formato, lea los comentarios en un archivo Fontmap de ejemplo enviado por Ghostscript. La lista anterior es la representación del mapa de fuentes como las tiendas de Ghostscript en su diccionario interno.

5

Un montón de buenas respuestas ya, pero nadie ha mencionado esto:

Al invocar Ghostscript, los -d y -s opciones de crear definiciones iniciales en systemdict. Esto le permite hacer parameterized invocation of your postscript program.

Utilice -dname[=token] para establecer el valor en nulo, o un número (o cualquier otro token postscript). Use -sname=string para establecer un valor de cadena (que en la mayoría de los contextos funciona tan bien como un nombre).

Y puede manipular todas las pilas hasta cierto punto con los operadores correctos.

  • token empuje para pila de operandos de cadena o archivo (esto es lo que utiliza el bucle intérprete para consumir el flujo de programa, así que esto es lo que estás usando ya sea de ingresar el código a través de un archivo o directamente desde el teclado)
  • pop descarte de pila de operandos
  • begin empuje para pila dict
  • end pop de pila dict
  • run, exec, %procedure-invocation empuje para pila ejecutivo
  • exit, stop pop o clara pila ejecutivo
  • gsave empuje GSTATE en los gráficos pila
  • grestore gráficos pop pila
  • save empuje una copia de todas las VM-contenidos (todos dicts y matrices, pero no cadenas) de memoria
  • restore rebobinado a estado guardado (revierten todas dicts y matrices a estado anterior)

Los diccionarios, al ser objetos compuestos, heredan una cantidad de operadores comunes a todos los objetos compuestos.

  • -typename- crear el objeto, por ejemplo, tamaño dict
  • length informe de objeto
  • put insertar un elemento
  • get recuperar un elemento
  • copy poblar un objeto con el contenido de otro objeto
  • forall hacer algo con cada elemento
  • *load elemento de recuperación alternativa (para diccionarios, load realiza una búsqueda con where y luego get; para las matrices, aload derrames de todo el contenido de la matriz en la pila de operandos)
  • *store alternativo elemento de inserción (para los diccionarios, store realiza una búsqueda con where y luego un put Si se encuentra, o def si no; para matrices, astore rellenos la matriz de los objetos en la pila)

Para esta suite, diccionarios añaden

  • def puesta en diccionario actual (parte superior de la pila dict)
  • known diccionario de consulta para un elemento
  • where consulta todos los diccionarios para el elemento de
  • maxlength ya no interesante después de PS Nivel 2 añadido que se expande automáticamente diccionarios y GC
  • dictstack copiar el dictstack en una matriz (tal vez usted quiere Búsqueda de abajo hacia arriba, se puede!)
  • nombres no precedido por una barra / son automáticamente load ed y, si es ejecutable, ejecutado
  • // mientras que token está construyendo un objeto postscript, cualquier nombre precedido por una doble barra es load ed y se lo reemplaza en la matriz de procedimientos. Esto es muy poderoso, ya que puedes imitar las macros de Lisp.

Editar: Una cosa más. Al crear un diccionario, hay una compensación de tiempo/espacio cuando elige el tamaño del diccionario. Los diccionarios casi con certeza se implementan como una tabla hash (en todos los intérpretes menos simples), y la mayoría de las funciones hash pueden evitar colisiones cuando la tabla está medio llena (Regla de oro: Utilice dictos de doble tamaño para la velocidad) . Desde el nivel 2, por supuesto, los diccionarios crecerán automáticamente cuando agregue tamaño + 1 elementos, presumiblemente asignando un nuevo diccionario de tamaño k * (donde k es probablemente 1.5 o 2); pero controlar los tamaños manualmente puede darte un impulso de velocidad. En el nivel 1, si no está haciendo una referencia múltiple de sus diccionarios, puede instalar un reemplazo para dictfull en errordict para aumentar el tamaño y volver a ejecutar el put (o def o lo que sea). Como el nivel 2 hace esto internamente, puede reemplazar todas las referencias.

+2

Impresionante, @luserdroog - muchas gracias por su aclaración! ¡Aclamaciones! – sdaau

Cuestiones relacionadas