Nein, Ruby führt keine Gesamtbetriebskosten durch. Es kann aber auch nicht nicht TCO führen.
Die Ruby-Sprachspezifikation sagt nichts über die Gesamtbetriebskosten aus. Es heißt nicht, dass Sie es tun müssen, aber es heißt auch nicht, dass Sie es nicht tun können. Darauf kann man sich einfach nicht verlassen .
Dies unterscheidet sich von Schema, bei dem die Sprachspezifikation erfordert, dass alle Implementierungen TCO ausführen müssen . Aber es ist auch anders als bei Python, wo Guido van Rossum mehrfach (das letzte Mal vor ein paar Tagen) sehr deutlich gemacht hat, dass Python-Implementierungen keine TCO durchführen sollten.
Yukihiro Matsumoto ist mit TCO einverstanden, er möchte einfach nicht alle Implementierungen dazu zwingen, dies zu unterstützen. Leider bedeutet dies, dass Sie sich nicht auf die Gesamtbetriebskosten verlassen können. Andernfalls ist Ihr Code nicht mehr auf andere Ruby-Implementierungen portierbar.
Einige Ruby-Implementierungen führen TCO durch, die meisten jedoch nicht. YARV unterstützt beispielsweise TCO, obwohl Sie (im Moment) eine Zeile im Quellcode explizit auskommentieren und die VM neu kompilieren müssen, um TCO zu aktivieren - in zukünftigen Versionen wird sie standardmäßig aktiviert, nachdem die Implementierung dies bewiesen hat stabil. Die Parrot Virtual Machine unterstützt TCO nativ, daher könnte Cardinal sie auch problemlos unterstützen. Die CLR unterstützt TCO, was bedeutet, dass IronRuby und Ruby.NET dies wahrscheinlich tun könnten. Rubinius könnte es wahrscheinlich auch tun.
JRuby und XRuby unterstützen TCO jedoch nicht und werden dies wahrscheinlich auch nicht tun, es sei denn, die JVM selbst erhält Unterstützung für TCO. Das Problem ist folgendes: Wenn Sie eine schnelle Implementierung und eine schnelle und nahtlose Integration in Java wünschen, sollten Sie stapelkompatibel mit Java sein und den Stapel der JVM so oft wie möglich verwenden. Sie können TCO ganz einfach mit Trampolinen oder einem expliziten Continuation-Passing-Stil implementieren, verwenden dann aber nicht mehr den JVM-Stack. Dies bedeutet, dass Sie jedes Mal, wenn Sie Java aufrufen oder von Java in Ruby aufrufen möchten, eine Art ausführen müssen Umwandlung, die langsam ist. Daher entschieden sich XRuby und JRuby für Geschwindigkeit und Java-Integration über TCO und Fortsetzungen (die im Grunde das gleiche Problem haben).
Dies gilt für alle Implementierungen von Ruby, die eng in eine Hostplattform integriert werden sollen, die TCO nicht nativ unterstützt. Ich denke zum Beispiel, dass MacRuby das gleiche Problem haben wird.
Update: Hier ist eine nette Erklärung der Gesamtbetriebskosten in Ruby: http://nithinbekal.com/posts/ruby-tco/
Update: Vielleicht möchten Sie auch das Juwel tco_method überprüfen : http://blog.tdg5.com/introducing-the-tco_method-gem/
In der Ruby-MRT (1.9, 2.0 und 2.1) können Sie die Gesamtbetriebskosten aktivieren mit:
Es gab einen Vorschlag, die Gesamtbetriebskosten in Ruby 2.0 standardmäßig zu aktivieren. Außerdem werden einige damit verbundene Probleme erläutert: Tail Call-Optimierung: Standardmäßig aktivieren?.
Kurzer Auszug aus dem Link:
quelle
Es kann haben, ist aber nicht garantiert:
https://bugs.ruby-lang.org/issues/1256
quelle
TCO kann auch kompiliert werden, indem vor dem Kompilieren einige Variablen in vm_opts.h angepasst werden: https://github.com/ruby/ruby/blob/trunk/vm_opts.h#L21
quelle
Dies baut auf den Antworten von Jörg und Ernest auf. Grundsätzlich kommt es auf die Umsetzung an.
Ich konnte Ernests Antwort nicht dazu bringen, an der MRT zu arbeiten, aber es ist machbar. Ich habe dieses Beispiel gefunden , das für MRT 1.9 bis 2.1 funktioniert. Dies sollte eine sehr große Anzahl drucken. Wenn Sie die TCO-Option nicht auf true setzen, sollte der Fehler "Stapel zu tief" angezeigt werden.
quelle