2013-10-24 9 views
6

Betrachten Sie die Ruby-Klasse Foo::Bar.Ruby Namespace mit einer Klasse vs. Modul?

Die Konvention ist für den Namespace 'Foo' ein Modul zu sein, aber es könnte genauso gut eine Klasse sein:

module Foo; class Bar; end; end 

Versus:

class Foo; class Bar; end; end 

Im zweiten Fall, Bar ist keine innere Klasse von Foo, es ist nur eine weitere Konstante, die auf dem Singleton von Foo definiert ist. Die Oberklasse ist in beiden Fällen Object und sie enthalten nur das Kernel-Modul. Ihre Vorfahrenketten sind identisch.

Also, neben Operationen, die Sie mit Foo abhängig von seiner Klasse machen können (instanziieren, wenn eine Klasse, erweitern/include wenn ein Modul), hat die Art des Namespace irgendwelche Auswirkungen auf Bar? Gibt es zwingende Gründe, einen Namen mit vielen Namen zu wählen?

Die einzigen seltsamen Dinge, die ich sehe, sind Foo::Bar.new.extend Foo bzw. Foo.new.class::Bar.

Meine eigene meistverbreitete Verwendung einer Klasse in einer Klasse definiert würde eine Helfer-Struktur/Klasse sein, die nur gemeint wird intern von der Klasse verwendet werden sollten:

class Foo 
    Bar = Struct.new(:something) do 
    def digest 
     puts "eating #{something}" 
    end 
    end 
    def eat(something) 
    Bar.new(something).digest 
    end 
end 

Die nächstgelegene ich zu dieser Diskussion gefunden ist in "Using Class vs Module for packaging code in Ruby".

+0

Interessanterweise sehe ich ein ähnliches Problem in Rails war const_missing http://bugs.ruby-lang.org/issues/2740 – BF4

Antwort

5

Die unmittelbarste Nutzen Module für Namespacing zu verwenden ist, dass Sie include den Namensraum importieren können, und die Konstanten in ihm unqualifizierte erklärt verwenden:

module Foo; class Bar; end; end 

module Elsewhere 
    include Foo 
    Bar.new 
end 
+0

Ok, ich kann das als ein überzeugendes Argument sehen, wo die Verwendung eines Moduls * beabsichtigt * sein soll. Aber wenn nicht beabsichtigt, wie die meisten Edelsteine, Das Mischen des oberen Namensraums des Edelsteins kann leicht zu Kollisionen mit vorhandenen Konstanten führen. – BF4

+0

Übrigens, wenn ich keine weiteren Antworten bekomme, akzeptiere ich das (ich habe es aufgepeppt), aber ich habe auf etwas vollständigeres gehofft. – BF4

+2

Sicher, danke. Die einzigen anderen Gründe, die mir einfallen, sind "Konvention" und "Absichtserklärung", von denen keine viel befriedigender ist. Klasse und Modul sind mechanisch so nah, weil Klasse eigentlich eine Unterklasse von Modul ist, die Instanziierung implementiert. Ich habe vorher gedacht, dass ein tatsächliches unabhängiges Namespace-Konstrukt nett sein könnte, aber ich bin mir nicht sicher, welches Verhalten es tatsächlich hinzufügen würde, also kann ich sehen, warum es jetzt alles mit Modulen gemacht wird. –

Verwandte Themen