Sie Ruby ‚require‘ innerhalb oder außerhalb der Klassendefinition Aussagen gehen?

StackOverflow https://stackoverflow.com/questions/605261

  •  03-07-2019
  •  | 
  •  

Frage

Wenn Klasse verwenden, um Dateien in Ruby, setzen Sie das ‚erfordert‘ Anweisungen an den Anfang der Datei oder innerhalb der Klassendefinition?

War es hilfreich?

Lösung

Technisch ist es nicht wirklich wichtig. require ist nur ein normaler Methodenaufruf, und der Umfang es in nicht genannt nicht beeinflussen, wie es funktioniert. Der einzige Unterschied Platzierung macht, ist, dass es ausgeführt wird, wenn unabhängig von Code sie gesetzt in ausgewertet wird.

Praktisch gesprochen, sollten Sie sie oben setzen, damit die Menschen der Datei Abhängigkeiten auf einen Blick sehen können. Das ist der traditionelle Ort für sie.

Andere Tipps

an der Spitze.

require 'rubygems'
require 'fastercsv'

class MyClass
  # Do stuff with FasterCSV
end

kann ich einen möglichen Grund sieht für keinen require am Anfang der Datei setzen: wo es ist teuer zu laden und nicht immer ausgeführt. Ein Fall, der mir einfällt, ist, wo zum Beispiel Code und seine Tests in der gleichen Datei sind, die etwas ist, Ich mag insbesondere von Zeit zu Zeit für kleine Bibliothek Code zu tun. Dann kann ich die Datei von meinem Editor ausführen und die Tests ausgeführt. In diesem Fall, wenn die Datei von anderswo required in ist, mag ich nicht test/unit geladen werden.

Etwas ein wenig wie folgt aus:

def some_useful_library_function()
  return 1
end

if __FILE__ == $0
  require 'test/unit'
  class TestUsefulThing < Test::Unit::TestCase
    def test_it_returns_1
      assert_equal 1, some_useful_library_function()
    end
  end
end

Es ist eigentlich egal, wo Sie sie setzen, aber wenn man sie hineingelegt ein class oder module Ausdruck, dann sieht es aus wie Sie importieren, was auch immer in der required-Datei in die Klasse des Namespace , das ist nicht wahr. alles endet im globalen Namespace (oder was auch immer Namespaces definiert ist in der Bibliothek )

besser Also, legen sie an der Spitze, um Verwechslungen zu vermeiden.

Am Anfang der Datei, die meisten (aber nicht alle) Sprachen verarbeiten Importe auf diese Weise. Ich finde es viel sauberer und einfacher, sie auf diese Weise zu behandeln.

Ich denke, dass es nur Sinn, auf diese Weise wirklich macht ... wie Sie auf halben Weg in einer Datei erhalten dann:

class Foo
  def initialize(init_value)
    @instance_var = init_value

# some 500 lines of code later....

  end
end

class Bar
# oh look i need an import now!
require 'breakpoint'

Wie Sie sehen können, wäre es sehr schwer sein, sie zu verfolgen. Ganz zu schweigen davon, wenn Sie die importierten Funktionen früher im Code verwenden wollen, würden Sie wahrscheinlich einen Rückzieher und schließt sie wieder, weil die andere Einfuhr spezifisch sein würde zu dieser Klasse. die gleichen Dateien importieren würde auch eine Menge Aufwand während der Laufzeit erstellen.

Ich glaube, dass die erforderlich Anweisung innerhalb der Klasse gehört. Mit Klassen bedeutet, dass wir eine grundlegende Lehre der OOP akzeptieren, sollten nämlich Objekte so locker wie möglich verbunden sein. Für mich bedeutet, externe Abhängigkeiten zu minimieren. Wenn ich später eine Klasse eine eigene Datei verschieben, will ich nicht haben zu brechen, weil ich nicht alle notwendigen aufzuspüren erforderlich Aussagen, dass die Klasse verbraucht.

Es verursacht keine Probleme haben doppelten erforderlich Anweisungen in einer Datei und es vereinfacht den Refactoring, die unweigerlich statt wird nehmen von den nächsten Programmierern, die Ihren Code erben.

Die meisten Antworten empfiehlt sich, die erfordert Anweisungen an den Anfang der Datei. Allerdings, wenn verschachtelte Klassen erfordern / Module, die Sie könnten sie in der Klasse zu prüfen, setzt statt (oben). Werfen Sie einen Blick auf dieses Beispiel:

# foo.rb
require './foo/bar'

class Foo < Struct.new(:name, :description)
  def bar
    Bar.new(self)
  end
end

# foo/bar.rb
class Foo
  class Bar < Struct.new(:foo)
  end
end

irb:

require './foo'
# ...
# TypeError (superclass mismatch for class Foo)

Dies geschieht, weil Bar ist innerhalb verschachtelt Foo und es wird als solche definiert müssen durch Verschachtelung der Bar Klasse innerhalb der foo Klasse. Da jedoch Foo ist noch nicht definiert es jetzt durch die verschachtelte Struktur definiert wird. Nach Bar erfolgreich erforderlich ist, versuchen wir nun die Foo Klasse zu definieren, die von einer anderen Klasse erbt. Dies scheitert aufgrund der Tatsache, dass Foo bereits definiert ist (durch die verschachtelte Struktur) und Vererbung können nur auf der Anfang Definition der Klasse auftreten. So erhöhen:

  

Typeerror (Super Mismatch für die Klasse Foo)

Dieses Problem kann einfach gelöst werden, indem die erfordern Anweisung innerhalb der beweglichen Foo Klasse.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top