witam
mam metode klasową, w klasie Task, powiedzmy
def self.parse_foo(foo)
foo["fffff"] = "gggg"
foo
end
otóż po wywołaniu tej metody przykładowo
bar = {"aaaa" => "bbbb"}
ret = Task.parse_foo(bar)
zmieniana jest także wartość parametru bar, tak jakby była przekazywana przez referencje a nie wartość. dlaczego tak się dzieje i jak tego uniknąć ? dodam że jeśli zrobie to samo dla cyfr a nie dla hashy metoda zachowuje sie normalnie.
Bo w rubym zmienne są przekazywane właśnie przez referencję. Możesz użyć metody clone (ale uważaj na zagnieżdzone hashe, wtedy musisz użyć np ActiveSupportowego deep dup)
To nie jest skomplikowane, chociaż wiem do czego dążysz. Nie zmieni to jednak faktu, że w rubim zmienne są przekazywane przez wartość. Gdyby były przekazywane przez referencje to poniższy program:
[code]def swap(a, b)
a, b = b, a
end
a, b = “foo”, “bar”
swap(a, b)
puts [a, b].join(" ")[/code]
wypisałby “bar foo”, a wypisuje “foo bar”. Natomiast to, że wewnętrznie przekazywaną wartością jest wskaźnik (referencja) do obiektu (ale nie do zmiennej), tylko że programista tego nie widzi, powoduje, że ludzie błędnie sądzą, że iż jest to referencja do zmiennej.
W c++ wskaźniki przekazywane są przez wartość i nie przeszkadza to na wewnętrzną zmianę reprezentacji obiektu na który wskazują.
Tudzież jestem w stanie zgodzić się na stwierdzenie, że zmienne przekazywane są przez wartość, a ich wartością jest referencja do obiektu (nie jest to jednak równoważne z przekazywanie przez referencje).
Mówiąc po prostu, że parametry są przekazywane przez wartość, jesteś tak samo precyzyjny, jakbyś powiedział, że są przekazywane przez referencję. I jedno i drugie bez dokładniejszego wyjaśnienia nie jest prawdą
I nie jest to tak samo równoważne przekazywaniu przez wartość bo to nie wartość obiektu jest przekazywana tak jak w przypadku typów primitive. Jeżeli chodzi o tą kwestię to zamiast ograniczać się do stwierdzeń przez wartość/przez referencję, wolę zwyczajnie powiedzieć “przez kopię referencji”
I nie jest to tak samo równoważne przekazywaniu przez wartość bo to nie wartość obiektu jest przekazywana tak jak w przypadku typów primitive. Jeżeli chodzi o tą kwestię to zamiast ograniczać się do stwierdzeń przez wartość/przez referencję, wolę zwyczajnie powiedzieć “przez kopię referencji” ;)[/quote]
Jest równoważne jeśli odpowiesz poprawnie na postawione wcześniej przeze mnie pytanie (“Co zawiera zmienna a?”).
Btw, nie napisałem, że przekazywana jest wartość obiektu. Przekazywana jest wartość zmiennej.
[quote=radarek]Jest równoważne jeśli odpowiesz poprawnie na postawione wcześniej przeze mnie pytanie (“Co zawiera zmienna a?”).
Btw, nie napisałem, że przekazywana jest wartość obiektu. Przekazywana jest wartość zmiennej.[/quote]
Ok… co zawiera zmienna a? yyyyy wartość “foo”?
Komplikujesz trochę wprowadzając taki termin jak wartość zmiennej, który wg Ciebie nie jest tym samym co wartość obiektu.
Jeżeli masz po prostu na myśli to, że przez wartość przekazywane są referencje obiektów, a nie same obiekty to chyba sie rozumiemy
Wprowadzam pojęcie wartość zmiennej, gdyż coś przecież ta zmienna musi zawierać :). Zmienna a nie zawiera “foo”, jest tylko do niej odniesieniem (referencją, ukrytym wskaźnikiem).
A co się dzieje gdy robisz:
a = "foo"
b = a
? Ano do zmiennej b przypisujesz wartość zmiennej a (w skrócie mówimy do zmiennej b przypisujemy zmienną a). Dokładnie to samo dzieje się gdy przekazujesz zmienną jako parametr do metody.
Co do referencji, tych znanych z c++ (bo chyba to jest typowy przykład języka, który takie referencje obsługuje?), w rubym nie zrobisz czegoś takiego:
[code=c++]#include
int main() {
int a = 123;
int &b = a;
b = 255;
printf("%d\n", a); // wypisze 255
return 0;
}[/code]
Właśnie dlatego, że zmienna nie może być referencją do drugiej zmiennej, a także dlatego, że zmienne nie są przekazywane przez referencje jako parametry metod.
Ależ wszystko sie zgadza radarek Tylko zobacz ile się trzeba tłumaczyć z takiego stwierdzenia, że parametry są przekazywane przez wartość, które jest poprawne, ALE ALE ALE tak na prawdę parametr nie jest tym czym myślisz, że jest (bo jak się okazuje - nie Twoim obiektem). Taka pół prawda wg mnie mąci tak samo w głowie jak historie o przekazywaniu przez referencje I tylko do tego mam w tym wątku zastrzeżenia