2015-04-20 21 views
13

W Rubim przypisujemy wartości do obiektów za pomocą operatora =.W jaki sposób przypisanie przypisania Ruby jest semantyczne?

połączeniu z niejawny wpisywanie i często się sytuacje tak:

myVar= :asymbol 

Powyższa linia zarówno tworzy nowy obiekt symbol, a wiąże się z obiektu do nazwy zmiennej myVar.

W sposób semantyczny jak to się dzieje?

miałem go młotkiem w głowę, że operator = jest nie magiczną składni wbudowany interpreter, ale w rzeczywistości po prostu cukier syntaktyczny dla metody object.=(value).

Mając to na uwadze, mój najlepszy przypuszczenie to, że gdy interpreter widzi staramy się przypisać wartość nieokreślonej nazwy zmiennej, najpierw tworzy nowy obiekt z jakiegoś szczególnego rodzaju, jak undefined lub null czy coś, i następnie przekazuje wiadomość do tego obiektu, przy czym ładunek jest wartością, którą próbujemy przypisać.

Jednak wywołanie .class na obiekcie nieinstalowanym wywołuje wyjątek, ponieważ Ruby myśli, że próbujemy wywołać metodę (której nazwa jest nazwą zmiennej, którą próbujesz wprowadzić) na numer self

> obj.class 
    > NameError: undefined variable or method 'obj' for main:Object 

Tak więc, o ile mogę powiedzieć, nie mam możliwości, aby to ustalić eksperymentalnie.


Notatka:

W przypadku przypisania symboli, wierzę, że wartość przypisana (AKA wartość zwracana przez object_id metoda instancji obiektu, AKA wartość unsigned long VALUE zmiennej w Poziom C) to liczba reprezentująca przesunięcie w tabeli (uważam, że właśnie w ten sposób Ruby osiąga "bezpośrednią wartość" dla obiektów symboli).

W innych przypadkach wartością może być bezpośrednie kodowanie samego obiektu lub wartość, która ma być rzutowana na wskaźnik w odniesieniu do struct.

Bez względu na to, w jaki sposób Rubin reprezentuje obiekt i czy ostatecznie przypisujemy referencję lub sam obiekt, nie jest to o to tutaj pytam.

dodatkowe pytanie:

Co klasa jest metoda = odziedziczone? Nie mogę znaleźć go w specyfikacji dla Object lub BasicObject.

+2

Np. "Nie ma łyżki", nie ma metody "=". – tadman

+0

Czy jest to duplikat tego pytania? http://stackoverflow.com/questions/8345755/object-assignment-in-ruby –

+0

@GeorgeStocker Zadane pytanie dotyczy ** efektu ** operatora '=', gdzie moje dotyczy jego implementacji w Ruby. – LukeP

Odpowiedz

13

Zmienne są w sensie technicznym tylko wskaźnikami do obiektów. Nie ma w tym nic nadzwyczajnego, ale proste przypisanie zmiennej do istniejącego obiektu nie wiąże się z żadnymi wywołaniami metod ani wysłaniem wiadomości.

Pamiętaj, że zmienne są właśnie tam, więc programiści mogą odwoływać się do obiektów po nazwie, zamiast do jakiegoś wewnętrznego identyfikatora lub lokalizacji pamięci.Więc jest tu trochę "magii", = jest wyjątkowy podczas wykonywania zadania, ponieważ istnieją zasady dotyczące tego, co możesz zrobić po lewej i prawej stronie.

Jedynym sposobem, w jaki można wysyłać wiadomości do czegoś, czyli wywoływać metody, jest zdefiniowanie go w sposób zrozumiały dla kompilatora. x = 1 jest wystarczający, oznacza to, że x odnosi się do danego Fixnum.

Należy zauważyć, że interpreter Ruby będzie musiał określić, czy x odnosi się do zmiennej lub wywołania metody, ponieważ x= może być metodą zdefiniowaną w kontekście obiektu, w którym jest ona oceniana.

Na przykład:

class Example 
    def x=(value) 
    @x = value 
    end 

    def test 
    # Equivalent to send(:x=, 1) because x= is a method 
    x = 1 

    # Is a variable definition because y= is not a method 
    y = 2 

    # Is always a method call because self is referenced. 
    self.x = 3 
    end 
end 

# Is a variable definition because x= is not defined in this context 
x = 4 

Jeśli nie ma x= metoda dla obiektu, x jest automatycznie uważana za zmienną.

Nie można uzyskać wiadomości o numerze :=, ponieważ oznaczałoby to, że można zastąpić jeden obiekt innym, co jest niedozwolone. Po utworzeniu obiektu nie można go zmienić w magiczny sposób. W tym celu należy utworzyć nową instancję innego obiektu. Zmienne pojawiają się tylko w celu zmiany typów, ale w rzeczywistości kończą się na wskazaniu różnych obiektów.

Krótko mówiąc, nie ma metody wywołania metody :=, ale mogą istnieć specjalne metody, takie jak :x=, które działają w bardzo szczególnych przypadkach.

+0

Dobra odpowiedź! ... –

+1

Inna sprawa: 'value =" newval "' jest zawsze uważane za zmienną (zamiast metody), chyba że istnieje wyraźny odbiorca. Więc jeśli twój kontekst zdefiniował ': value =', musisz jawnie wywołać 'self.value = arg', aby uzyskać dostęp do tej metody. – acsmith

+0

@smsmith To staje się problemem, gdy metoda jest wprowadzana po skompilowaniu kodu. Słuszna uwaga. – tadman

Powiązane problemy