2009-06-10 14 views
17

Próbuję zrozumieć następujący kod Rubiego.Wywoływanie self.send iteracyjnie na argumentach mieszania w celu zainicjowania()

Wygląda na to, że attrs to skrót, który jest przekazywany jako argument z domyślną wartością pustego hasha.

Następnie attrs.each iteruje po kluczach, pary wartości w haszdzie (|k,v|).

Jaki efekt uzyskuje się, wywołując self.send na elementach pary klucz-wartość podczas tej iteracji?

def initialize(attrs = {}, *args) 
    super(*args) 
    attrs.each do |k,v| 
    self.send "#{k}=", v 
    end 
end 
+0

+1 Uwielbiam używając tego kodu na elastyczne tworzenie/inicjowanie obiektu. Zobacz mój answer @ http://stackoverflow.com/questions/1778638/idiomatic-object-creation-in-ruby/5272354#5272354 – abe

Odpowiedz

21

send wywołuje metody w pierwszy parametr i przekazuje reszty parametrów jako argumentów.

W tym przypadku przyjmuję, co jest w attrs jest listą atrybutów. Powiedzmy, że jest to coś takiego:

{ :name => "John Smith" } 

Więc następnie w pętli, to robi to:

self.send "name=", "John Smith" 

co jest równoważne

self.name = "John Smith" 
+0

Cool. Dzięki. Oznacza to, że w twoim przykładzie nazwa staje się metodą klasową, prawą - z powodu [self.] Nazwy? – franz

+2

Po pierwsze, ten przykład wcale nie tworzy metody - to wywołanie metody "name =", która musi już istnieć. Po drugie, self wewnątrz metody instancji (takiej jak initialize) odnosi się do instancji. To wywołuje metodę instancji. – Chuck

+0

Warto wspomnieć, że metody 'name =' są automatycznie tworzone przez pomocnika 'attr_accessor: name'. –

Powiązane problemy