2013-01-14 13 views
5

W Ruby, podczas tworzenia nowej klasy, będziemy definiować metody konstruktora tak:Dlaczego możemy zdefiniować `# initialize` zamiast` :: new`

class Thing 
    def initialize 
    do_stuff 
    end 
end 

Jednak, gdy faktycznie tworzenia instancji obiekt nie znajduje się pod adresem initialize na instancji, ale na klasie new.

W związku z tym, dlaczego nie zdefiniujemy zamiast tego ::new?

class Thing 
    def self.new 
    do_stuff 
    end 
end 

Czy istnieje coś ::new robi beind kulisami że initalize nie definiuje? Czy w ogóle są te dwie różne? Czy zdefiniowałbyś pracę w trybie ::new? Czy tylko to, że def initialize jest krótszy (nie) niż def self.new?

Myślę, że musi istnieć dobry powód do rozbieżności.

+0

http: //blog.sidu.w/2007/12/rubys-new-as-factory.html –

Odpowiedz

10

Nowy przydziela miejsce dla nowego obiektu i tworzy go. Następnie wywołuje metodę inicjowania obiektów w celu utworzenia nowego obiektu przy użyciu przydzielonej pamięci. Zwykle jedyną częścią, którą chcesz dostosować, jest faktyczne tworzenie iz przyjemnością pozostawiasz przydział pamięci za pomocą metody Object.new, więc piszesz metodę initialize. Co nowego robi pod maską wygląda mniej więcej tak (z wyjątkiem C):

class Object 
    def self.new(*args, &block) 
     object = allocate 
     object.send(:initialize, *args, &block) 
     return object 
    end 
end 

Więc kiedy zadzwonisz Object.new, co faktycznie dzieje:

1) Pamięć jest przydzielana 2) uruchamiana jest metoda inicjowania obiektów.

+0

http://www.ruby-forum.com/topic/61666 –

3
  • Opracowanie punktu Abrahama, w efekcie, to odwrócenie relacji zawijania. Jeśli miałbyś prymitywną wersję allocate i zwykle zdefiniowałeś new, zawsze musiałbyś robić typowe rzeczy, jak wywoływanie allocate i zwracanie obiektu na końcu, co jest zbędnym zadaniem. Posiadając new i initialize, pierwszy będzie opakował drugi, więc musisz tylko zdefiniować, co jest opakowane, a nie opakowanie.
  • new to metoda klasy, więc jeśli ją zdefiniujesz, nie masz dostępu do metod instancji i zmiennych instancji domyślnie i musisz polegać na akcesoriach. Z drugiej strony, initialize jest metodą instancji, więc łatwiej będzie pracować ze zmiennymi instancji i metodami instancji.
5

Aby zapewnić dostęp do zmiennych instancji.

Zmienne wystąpienia, takie jak @value, są dostępne tylko z instancji, ale nie z metody klasy. Różni się to od języków takich jak Java, gdzie prywatne zmienne instancji mają klasę, a nie zakres instancji, a zatem są dostępne z konstruktora statycznego.

class Thing 
    def initialize 
    @value = 42 
    end 
end 

class Thing 
    def self.new 
    # no way to set the value of @value !!!!!!!! 
    end 
end 

Dla zainteresowanych historią Ruby, model obiektowy z instancyjnymi zmiennymi instancji wraca do Smalltalk. I znajdziesz taki sam wzór we współczesnym dialekcie Smalltalk, takim jak Pharo, new, zaimplementowanym w Object, który wywołuje self initialize, dzięki czemu podklasy mogą z łatwością inicjować zmienne instancji.

+0

to nie zmienia faktu, że nie znoszę używać słowa "zainicjować" to powinno być nazywane post initialize lub coś w moim świecie :) – rogerdpack

Powiązane problemy