2010-08-24 10 views
8

Me pregunto, ¿-MO=Deparse le muestra todas las optimizaciones de Perl, y por qué no se dobla en Perl 5.10?¿Cómo funciona O = Deparse y tiene Perl y doblar matrices constantes?

$ perl -MO=Deparse -e'[qw/foo bar baz/]->[0]' 
['foo', 'bar', 'baz']->[0]; 
-e syntax OK 

Algunos pensaban que en el IRC O=Deparse no podría estar mostrando todo, pero sin duda alguna muestra de constantes.

$ perl -MO=Deparse -e'use constant "foo" => "bar"; foo' 
use constant ('foo', 'bar'); 
'???'; 
-e syntax OK 

mismo resultado si yo escribo de manera explícita la sub constante. Aunque es predecible, también es bastante interesante que la documentación en constant.pm crea una lista de constante en lugar de matriz constante. Supongo que no solo no se pliega como constantes escalares sino que requiere la sobrecarga de crear una nueva matriz en cada invocación.

$ perl -MO=Deparse -e'use constant foo => qw/foo bar baz/; (foo)[0]' 
use constant ('foo', ('foo', 'bar', 'baz')); 
(foo)[0]; 
-e syntax OK 

La única conclusión que puedo llegar a es -MO=Deparse está mostrando todo el plegado y matrices constantes no están optimizados en Perl? ¿Es esto así? ¿Hay alguna razón técnica para ello?

+1

Todavía estoy confundido, ¿por qué estoy recibiendo un downvoted por esto? Alguien déjame una línea. ¿Es porque la pregunta es demasiado esotérica? ¿Crees que implicará mucho trabajo para cualquier ganancia? Solo estaba preguntando si se podía hacer, y por qué no se hizo. La [respuesta principal] (http://stackoverflow.com/questions/3561210/how-does-odeparse-work-and-does-perl-have-and-fold-constant-arrays/3561323#3561323) parece pasar por las mismas preguntas que estoy preguntando (1) Supongamos que no se puede hacer por razones técnicas (2), luego supongamos que simplemente no se hace, (3) luego especulemos que no está hecho porque no importa lo suficiente. –

Respuesta

9

No puede crear matrices constantes porque las matrices no son datos. Perl 5 tiene cinco tipos de datos (cosas que se pueden almacenar en variables):

  • ningún valor (UNDEF)
  • números
  • cadenas
  • referencias
  • listas (formados por uno o más de los tipos anteriores)

Usted puede hacer una constante de cualquiera de ellos. Perl 5 también tiene tres recipientes:

  • Scalar
  • de matriz
  • Hash

escalares puede contener cualquiera de los primeros cuatro tipos de datos, matrices y hashes puede contener listas. Es importante no confundir las cosas que contienen los datos y los datos en sí.

En cuanto a B::Deparse, vuelca el optree una vez que está construido, por lo que mostrará los resultados de todos los pliegues constantes.

No lo he pensado lo suficiente todavía, pero no veo ninguna razón obvia de que no se haya podido plegar.

+1

¿Podría explicar '-MO = Deparse -e'use strict; print {} -> [1] 'vs' use strict; print {} -> [1] '. En algún momento, estricto sabe que está tratando de obtener una referencia inválida para un elemento n-ésimo (es decir, que '{}' es una referencia hash). Sé que decimos proverbialmente que el estado estricto opera en tiempo de compilación. ¿Cómo sabe el estricto qué tipo de referencia es esta? ¿Podrías explicar un poco más en esa dirección? –

+1

@Evan Carroll El estricto pragma no capta eso, solo se preocupa por la declaración de variables ('" vars "'), la prohibición de referencias simbólicas ('" refs "') y la prohibición de la mayoría de las cadenas de palabras simples ('" subs "') Las referencias al operador '->' en el tiempo de ejecución, por lo que no obtenemos un error hasta entonces. Si hiciéramos '->' doblar constantes, probablemente podríamos detectar ese error específico en tiempo de compilación. –

+0

La regla de oro siempre ha sido que 'strict' no ralentiza el tiempo de ejecución. Las cosas que hacían eso estaban reservadas para 'warnings.pm'. ¿Tan estricto es hacer un pase sobre el op-tree en tiempo de ejecución durante BEGIN {} y lanzar la excepción, o strict es afirmar que el reftype es válido a un costo de velocidad durante el tiempo de ejecución? - O, todavía no lo entiendo. –

8

No se puede crear una matriz constante en Perl, no hay nada en el interior que indique una matriz constante o hash o incluso un escalar. "usar constante" aprovecha la capacidad de Perl para subrutinas en línea con un prototipo de () y un código simple. Lo mejor que puede hacer es establecer el indicador readonly, pero eso se puede desactivar en tiempo de ejecución.

Perl podría usar el indicador de solo lectura en tiempo de compilación como una sugerencia para indicar que la matriz realmente es de solo lectura y luego en línea cualquier acceso usando un índice constante. Dicha heurística probablemente sería segura ya que se supone que la bandera de solo lectura no es accesible para el usuario y probablemente no deba voltearse.

+1

..y si lo haces, te mereces lo que obtienes :) – Ether

Cuestiones relacionadas