2010-08-24 6 views
8

Ich frage mich, zeigt -MO=Deparse Ihnen alle Perl-Optimierungen, und warum wird dies nicht in Perl 5.10 gefaltet?Wie funktioniert O = Deparse, und hat Perl konstante Arrays?

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

im IRC Einige dachten, dass O=Deparse vielleicht nicht alles, zeigen, aber es zeigt sicherlich eine gewisse Konstante Faltung.

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

gleiche Ergebnis, wenn ich ausdrücklich die konstante Unter schreiben. Obwohl vorhersehbar, ist es auch interessant, dass die Dokumentation in constant.pm haben Sie eine Konstanten Liste anstelle einer Konstante Array erstellen. Ich nehme an, dass dies nicht nur wie skalare Konstanten gefaltet ist, sondern dass es den Aufwand erfordert, bei jedem Aufruf ein neues Array zu erstellen.

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

Die einzige Schlussfolgerung, die ich ist -MO=Deparse kommen kann, ist alle die Faltung zeigt, und konstanten Arrays werden in Perl nur nicht optimiert heraus? Ist das so? Gibt es einen technischen Grund dafür?

+1

Ich bin immer noch verwirrt, warum werde ich dafür downvoted? Jemand sagt mir Bescheid. Liegt es daran, dass die Frage zu esoterisch ist? Sie glauben, es wird zu viel Arbeit für jeden Gewinn führen? Ich habe nur gefragt, ob es gemacht werden könnte und warum es nicht gemacht wird. Die [führende Antwort] (http://stackoverflow.com/questions/3561210/how-does-deparse-work-and-does-perl-have-and-fold-constant-arrays/3561323#3561323) scheint durchzugehen die gleichen Fragen, die ich stelle. (1) Angenommen, es kann nicht aus technischen Gründen getan werden (2), dann wird angenommen, dass es einfach nicht gemacht wird, (3) dann spekulieren, dass es nicht getan wird, weil es nicht wichtig genug ist. –

Antwort

9

Sie können keine konstanten Arrays erstellen, da Arrays keine Daten sind. Perl 5 hat fünf Arten von Daten (Dinge, die in Variablen gespeichert werden können):

  • keinen Wert (undef)
  • Zahlen
  • Saiten
  • Referenzen
  • Listen (bestehend aus einem oder mehr von den vorherigen Typen)

Sie können aus jedem eine Konstante machen. Perl 5 hat auch drei Behälter:

  • Scalar
  • Array
  • Hash

Skalare halten kann jeder der ersten vier Arten von Daten, Arrays und Hashes Listen aufnehmen kann. Es ist wichtig, Dinge, die Daten und Daten enthalten, nicht zu verwechseln.

Wie für B::Deparse, Dumps die optree, nachdem es gebaut ist, so wird es die Ergebnisse aller konstanten Faltung zeigen.

Ich habe noch nicht genug darüber nachgedacht, aber ich sehe keine offensichtlichen Gründe, dass es nicht gefaltet werden konnte.

+1

Können Sie erklären, '-MO = Deparse -e'use strict; print {} -> [1] 'vs' use strict; drucke {} -> [1] '. An einem bestimmten Punkt weiß strict, dass Sie versuchen, eine ungültige Referenz für ein N-tes Element zu erhalten (dh dass '{}' ein Hash-Ref) ist. Ich weiß, dass wir sprichwörtlich sagen, dass der Zustand, in dem strikt operiert wird, Kompilierzeit ist. Wie weiß genau, welche Art von Referenz das ist? Könntest du vielleicht ein bisschen mehr in diese Richtung erklären? –

+1

@Evan Carroll Das strikte Pragma fängt das nicht ein, es interessiert nur die Deklaration von Variablen ('" vars "'), verbietet symbolische Referenzen ('" refs ") und verbietet die meisten bareword Strings (' "subs" ')). Der '->' Operator dereferenziert zur Laufzeit, weshalb wir bis dahin keinen Fehler bekommen. Wenn wir '->' konstante Faltung machen, könnten wir wahrscheinlich diesen spezifischen Fehler zur Kompilierzeit abfangen. –

+0

Die Faustregel war immer, dass 'strict' die Laufzeit nicht verlangsamt. Dinge, die das taten, waren reserviert für 'warnings.pm'. So strikt macht einen Durchlauf über den OP-Baum zur Laufzeit während BEGIN {} und wirft die Ausnahme, oder strict behauptet, dass der RefType mit einer Geschwindigkeit Kosten während der Laufzeit gültig ist? - Oder verstehe ich es immer noch nicht? –

8

Sie können kein konstantes Array in Perl erstellen, es gibt nichts in den Interna, um ein konstantes Array oder Hash oder sogar einen Skalar anzugeben. "use constant" nutzt Perls Fähigkeit, Unterroutinen mit einem Prototyp von () und einfachem Code zu inline zu schreiben. Das Beste, was Sie tun können, ist das Flag readonly, das aber zur Laufzeit ausgeschaltet werden kann.

Perl könnte das Readonly-Flag zur Kompilierzeit als einen Hinweis verwenden, um anzuzeigen, dass das Array tatsächlich nur gelesen wird, und dann jeden Zugriff mit einem konstanten Index inline. Eine solche Heuristik wäre wahrscheinlich sicher, da das Readonly-Flag nicht für Benutzer zugänglich sein sollte und Sie es wahrscheinlich nicht abschalten sollten.

+1

..und wenn Sie das tun, verdienen Sie, was Sie bekommen :) – Ether

Verwandte Themen