2009-08-09 18 views
9

tą metodą:Kiedy używać „ja” w Ruby

def format_stations_and_date 
    from_station.titelize! if from_station.respond_to?(:titleize!) 
    to_station.titleize! if to_station.respond_to?(:titleize!) 
    if date.respond_to?(:to_date) 
     date = date.to_date 
    end 
    end 

katastrofy z tym błędem podczas date jest zerowa:

NoMethodError (You have a nil object when you didn't expect it! 
The error occurred while evaluating nil.to_date): 
    app/models/schedule.rb:87:in `format_stations_and_date' 
    app/controllers/schedules_controller.rb:15:in `show' 

Jednak jeśli zmienię date = date.to_date do self.date = self.date.to_date metoda działa poprawnie .

Co się dzieje? W ogóle, kiedy muszę napisać self?

Edytuj: Nie jest to związane z pytaniem, ale pamiętaj, że nie ma "titleize!" metoda.

+0

możliwy duplikat [Dlaczego setery ruby ​​potrzebują "self". kwalifikacja w klasie?] (http://stackoverflow.com/questions/44715/why-do-ruby-setters-eded-self-qualification-within-class) –

Odpowiedz

42

Ilekroć chcesz wywołać metodę ustawiającą samodzielnie, musisz napisać self.foo = bar. Jeśli po prostu napiszesz foo = bar, parser ruby ​​rozpoznaje to jako zmienne przypisanie i od teraz myśli o foo jako zmiennej lokalnej. Aby parser zrozumiał, że chcesz wywołać metodę ustawiającą, a nie przypisywać zmiennej lokalnej, musisz napisać obj.foo = bar, więc jeśli obiekt jest self, self.foo = bar

7

Rozplątujesz się między nazwą metody instancji a zmienną lokalną za pomocą self (dozwolone jest posiadanie obu o tej samej nazwie w tym samym zasięgu). Innymi słowy, rozpoznawanie nazw metod będzie możliwe tylko wtedy, gdy w zasięgu nie będzie lokalnej ani blokowej zmiennej o tej samej nazwie. Oto:

class Foo 
    attr_accessor :boo 
    def do_boo 
    boo = 123 
    puts "Locvar: #{boo} Method: #{self.boo}" 
    end 
end 
Foo.new.do_boo 

Oto dlaczego: wyobraź sobie, że masz moduł, który implementuje metodę. Ta metoda przypisuje coś do wewnętrznej zmiennej lokalnej "foo", która jest używana do niektórych obliczeń. Jeśli pominiesz część "self", metoda wykona wywołanie metody "foo =" na obiekcie , którego klasa zawiera moduł, który nie był intencją autora i może być wręcz katastrofalny.

class Foo 
    def bar=(new_value_of_bar) 
    set_off_nukes(new_value_of_bar/3) 
    end 
end 

module InnocentModule # written by a different author elsewhere 
    def do_useful_stuff 
    ... 
    bar = Math.sin(something) # we're dead 
    end 
end 
Foo.send(:include, InnocentModule) 

Innym kluczowym elementem, gdzie trzeba używać samo jest podczas wywoływania metody klasy Object #, bo po prostu mówiąc: „klasa” oznacza słowo kluczowe klasa dla Ruby.

Powiązane problemy