2009-08-26 17 views
11

W trakcie korzystania z metody "tap" na obiektach typu "String" natknąłem się na interesujący problem.Metoda "dotknij" na obiekcie String nie zwraca oczekiwanego wyniku.

"abc".tap { |o| o = "xyz" } # this line returns "abc" instead of "xyz" 

Metoda "dotknij" działa na obiektach innych typów.

[].tap { |o| o << "xyz" } # this line returns ["xyz"] as expected 

Używam Rails 2.3.2 i Ruby 1.8.6 na Windows XP.

Czego mi tu brakuje?

Aktualizacja 1: Rozwiązałem ten problem. To był błąd użytkowania z mojej strony. W pierwszym scenariuszu ponownie przypisałem wartość do parametru bloku, zamiast go modyfikować. Byłem w stanie przepisać kod i uzyskać oczekiwany wynik.

"abc".tap { |o| o.replace "xyz" } 

Aktualizacja 2: Kod używany tutaj ma jedynie na celu wykazanie problemu. Mój rzeczywisty kod nie wygląda tak.

+0

Czy możemy mieć prawdziwy przykład tego, co próbujesz zrobić? –

+1

Rozwiązałem ten problem. To był błąd użytkowania z mojej strony. W pierwszym scenariuszu ponownie przypisałem wartość do parametru bloku, zamiast go modyfikować. Udało mi się przepisać kod i uzyskać oczekiwany wynik. "abc" .tap {| o | o.replace "xyz"} –

Odpowiedz

8

Stuknij # obiekt zawsze zwraca pierwotny obiekt przekazany do niego po wykonaniu bloku, nawet jeśli blok zwróci coś innego.

Zaletą jest to, że można wcisnąć w środek łańcucha i przetestować wartość obiektu bez modyfikowania wartości początkowej.

Oznacza to, że jeśli przekażesz "abc" do kranu, wykona blok i zwróci "abc". Twoje zadanie do o nic nie znaczy ze względu na zakres. Podobnie, jeśli przekażesz pustą tablicę do kranu, zwróci ona pustą tablicę z powrotem. Jednak w twoim drugim przykładzie zmodyfikowałeś oryginalną wartość. Operacje, które modyfikują oryginał, takie jak < < lub gsub! lub podobnie zmodyfikuje obiekt przed jego zwróceniem, dlatego otrzymasz inną wartość z powrotem.

Zapoznaj się z http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions, aby uzyskać więcej ciekawych przykładów użycia kranu. Nie używaj go do zadań lub modyfikacji, bo możesz odzyskać wygórowane wyniki.

Aktualizacja: do edycji, dlaczego to rozwiązuje problem? Nie rozumiem, dlaczego zadzwoniłbyś, by zrobić zamianę, kiedy możesz po prostu wywołać zamianę na samym obiekcie. Jakie korzyści daje ci dostaniesz?

+2

Tak, nie ma sensu używać "dotknij", aby zrobić prostą zamianę. Mój rzeczywisty kod nie wygląda tak. Zamiast publikować duży fragment kodu, wymyśliłem ten przykład, aby odtworzyć problem. Używam "dotknij" do debugowania. Ostatnio zacząłem używać "dotknij" zamiast "powrotu". Po ponownym przeczytaniu kodu źródłowego Rails dla metody dotknięcia, mój błąd stał się oczywisty. –

Powiązane problemy