2013-10-24 10 views
6

Rozważ klasę Ruby: Foo::Bar.Wyznaczanie nazw Ruby klasą a modułem?

Konwencja jest dla przestrzeni nazw 'foo', aby być moduł, ale może równie dobrze być klasą:

module Foo; class Bar; end; end 

Versus:

class Foo; class Bar; end; end 

W drugim przypadku, Bar nie jest wewnętrzną klasą Foo, jest to po prostu kolejna stała zdefiniowana w singletonie Foo. Nadklasa jest Object w obu przypadkach i zawierają tylko moduł Kernela. Ich łańcuchy przodków są identyczne.

Tak więc, oprócz operacji, które można wykonać przy pomocy Foo w zależności od klasy (tworzenie instancji, jeśli klasa, rozszerzenie/uwzględnienie, jeśli moduł), czy przestrzeń nazw ma wpływ na Bar? Czy istnieją ważne powody, aby wybrać jedną z wielu odstępów między nazwami?

Jedyne dziwne rzeczy, które widzę, to: Foo::Bar.new.extend Foo i Foo.new.class::Bar.

Moja własna najbardziej powszechne stosowanie klasy zdefiniowanej w klasie byłoby pomocnik struct/klasy, która ma być używana tylko wewnętrznie przez klasę:

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

najbliżej znalazłem do tej dyskusji jest w "Using Class vs Module for packaging code in Ruby".

+0

Co ciekawe, widzę tam był powiązany problem w Rails using const_missing http://bugs.ruby-lang.org/issues/2740 – BF4

Odpowiedz

5

Najbardziej natychmiastowe korzyści przy użyciu modułów do przestrzeni nazw jest to, że można użyć include zaimportować przestrzeń nazw i używać stałe zadeklarowane w nim bez zastrzeżeń:

module Foo; class Bar; end; end 

module Elsewhere 
    include Foo 
    Bar.new 
end 
+0

Ok, widzę to jako przekonujący argument, w którym użycie modułu jest * przeznaczone * do mieszania. Ale jeśli nie jest zamierzone, jak większość klejnotów, mieszanie górnej przestrzeni gema może powodować kolizje z istniejącymi stałymi. – BF4

+0

BTW, jeśli nie dostanę więcej odpowiedzi, zaakceptuję to (zrobiłem to), ale miałem nadzieję na coś bardziej kompletnego. – BF4

+2

Pewnie, dzięki. Jedyne inne powody, dla których mogę myśleć to "konwencja" i "wyjaśnienie zamiaru", z których żadna nie jest o wiele bardziej satysfakcjonująca. Klasa i moduł są tak blisko mechaniczne, ponieważ klasa jest faktycznie podklasą modułu, który implementuje instancję. Pomyślałem wcześniej, że rzeczywisty niezależny konstrukt przestrzeni nazw może być przyjemny, ale nie jestem pewien, jakie zachowanie to rzeczywiście doda, więc widzę, dlaczego teraz wszystko odbywa się za pomocą modułów. –

Powiązane problemy