2012-11-14 7 views
6

Mein Verständnis von Ruby war, dass das 'neue' Schlüsselwort immer mit einem Klassennamen kombiniert wurde, um eine neue Instanz einer Klasse zu erstellen. In dem folgenden Code, der unter https://gist.github.com/e9c0da1a6e92dd12cbc7 gefunden wurde, der als Lösung für einen Ruby Programming Challenge für Newbies-Wettbewerb eingereicht wurde, verwendet der Autor dreimal das Schlüsselwort "new", ohne eine Klasse zu instanziieren.Ruby: 'neu' ohne Klasse

In einem Fall wird new (0,0) einer Konstanten CLOSED zugewiesen. In einem anderen Fall ist new (open, close) ein Rückgabewert einer Funktion. Warum so? Was macht "neu", wenn es so benutzt wird? Was schafft es?

class OpenHours 

    attr_reader :open, :close 

    def initialize(open, close) 
     @open, @close = open, close 
    end 

    def duration 
     @duration ||= @open < @close ? @close - @open : 0 
    end 

    CLOSED = new(0, 0)    #first new 


    def self.parse(open, close) 
     open = Time.parse(open) 
     close = Time.parse(close) 


     open = TimeUtils::seconds_from_midnight(open) 
     close = TimeUtils::seconds_from_midnight(close) 


     new(open, close)      #second new 

    end 

    def offset(seconds) 
     self.class.new([@open, seconds].max, @close)  #third new 
    end 

    end 

Antwort

5

Wenn der Empfänger self ist, der Empfänger foo zugeordnet werden kann weggelassen werden. Die ersten beiden new-Aufrufe, die Sie in Frage stellen, werden im Kontext von OpenHours aufgerufen, was bedeutet, dass self auf OpenHours festgelegt ist. Daher entspricht new ohne den expliziten Empfänger self.new und OpenHours.new. In Ihrem dritten Beispiel ist der Kontext eine Instanz von OpenHours. self bezieht sich auf diesen Fall und self.class bezieht sich auf OpenHours, so dass self.class.new äquivalent zu OpenHours.new ist. In allen Fällen ist das erstellte Objekt eine Instanz von OpenHours.

6

In Ruby new ist nicht ein Operator oder Stichwort. Es ist eine Instanzmethode von Class Instanzen. Beispielsweise ist das Objekt OpenHours eine Klasse und daher eine Instanz von Class und verfügt daher über eine Instanzmethode new.

0

OpenHours :: CLOSED ist eine Instanz OpenHours

irb(main):034:0> OpenHours::CLOSED 
=> #<OpenHours:0x3ee2e85d @open=0, @close=0> 
irb(main):035:0> OpenHours::CLOSED.class 
=> OpenHours 

Um ehrlich zu sein, weiß ich nicht, was sie hier tun. Ich denke, es ist schlechter Code.

Antworten Kommentar: Wenn Sie foo = OpenHours.parse(open, close) tun, dann wird die Instanz

+0

Also gibt die Methode self.parse eine Instanz neu (open, close) von OpenHours zurück? Sollte es nicht etwas zugewiesen werden? – BrainLikeADullPencil