Idealerweise würde ich gerne sehen, was sich im Block super().tap { |o|
befindet, denn obwohl das wie eine schlechte Praxis aussieht, ist vielleicht nur eine Interaktion erforderlich, bevor oder nachdem initialize
aufgerufen wird.
Ohne Kontext ist es möglich, dass Sie nur etwas betrachten, das funktioniert, aber in Ruby nicht als gute Praxis angesehen wird.
Der Ansatz der separaten Methoden self.new
und initialize
ermöglicht es dem Framework-Designer jedoch, einen Teilklassen-fähigen Teil des Frameworks zu implementieren und dennoch sicherzustellen, dass die für das Framework erforderlichen Einstellungen ohne eine leicht umständliche Dokumentation, die ein bestimmtes erfordert, durchgeführt werden Verwendung von super()
. Es wäre eine leichter zu dokumentierende und sauberere API, wenn der Endbenutzer die Funktionalität erhält, die er nur mit der Unterklasse class MyClass < FrameworkClass
erwartet und ohne zusätzliche Hinweise wie:
Wenn Sie die Unterklasse initialize
implementieren, denken Sie daran, super
an den Anfang zu setzen, sonst funktioniert die Magie nicht
. . . persönlich würde ich dieses Design als fragwürdig empfinden, aber ich denke, dass es zumindest eine klare Motivation geben würde.
Es könnte tiefere Ruby-Gründe geben, Code in einem benutzerdefinierten self.new
-Block laufen zu lassen - zum Beispiel kann es dem Konstruktor erlauben, das spezifische Objekt zu wechseln oder zu ändern (sogar ein Objekt einer anderen Klasse zurückzugeben), bevor es es zurückgibt. Allerdings habe ich solche Dinge selten in der Praxis gesehen, es gibt fast immer einen anderen Weg, die Ziele eines solchen Codes zu erreichen, ohne new
anzupassen.
Beispiele für benutzerdefinierte / verschiedene Class.new
-Methoden, die in den Kommentaren angesprochen wurden:
-
Struct.new , das optional ein Klassenname und Rückgabeobjekte dieser dynamisch erstellten Klasse.
-
In-table-Vererbung für ActiveRecord , die ermöglicht dem Endbenutzer, ein Objekt unbekannter Klasse aus einer Tabelle zu laden und das richtige Objekt zu erhalten.
Letzteres könnte möglicherweise mit einem anderen ORM-Design für die Vererbung vermieden werden (obwohl alle diese Schemata Vor- / Nachteile haben).
Der erste (Structs) ist der Kern der Sprache, also muss er jetzt so funktionieren (obwohl die Designer einen anderen Methodennamen gewählt haben könnten).