Używanie Symboli Ruby

Pierwszy raz próbowałem nauczyć się Rubiego 2 lata temu, teraz zacząłem od nowa. Powodem, dla którego przestałem, było to, że nie mogłem zrozumieć klasy symboli. A teraz znowu jestem w tym samym momencie, całkowicie zagubiony w tym, kiedy i dlaczego używasz symboli. Przeczytałem inne posty na Stackoverflow, a także Wygooglowałem kilka wyjaśnień. Ale jeszcze tego nie rozumiem.

Najpierw myślałem, że symbole są tylko sposobem na stworzenie jakiejś "stałej nazwanej" bez konieczności przechodzenia przez to samo proces jak w powiedzmy Java.

:all 

Zamiast tworzenia stałej o dowolnej wartości public static final String ALL = 8;

Jednak nie ma to większego sensu, gdy używasz go np. attr_accessor :first_name etc. Czy symbole to tylko lekka Klasa strun? Mam problemy ze zrozumieniem, jak powinienem interpretować, kiedy i jak używać symboli zarówno w moich własnych klasach, jak i w frameworkach.

Author: Sam Rad, 2012-07-12

4 answers

W skrócie, symbole lekkimi łańcuchami, ale są również niezmienne i nie-śmieci-zbierane.

Powinieneś Nie używać ich jako niezmiennych ciągów w zadaniach przetwarzania danych (pamiętaj, że po utworzeniu symbolu nie można go zniszczyć). Zazwyczaj używasz symboli do nazywania rzeczy.

# typical use cases

# access hash value
user = User.find(params[:id])

# name something
attr_accessor :first_name

# set hash value in opts parameter
db.collection.update(query, update, multi: true, upsert: true)  
Weźmy pierwszy przykład, params[:id]. W umiarkowanie dużej aplikacji rails mogą być setki / tysiące tych rozrzuconych po bazie kodowej. Jeśli uzyskamy dostęp do tej wartości z łańcuchem params["id"], oznacza to przydzielanie nowych łańcuchów za każdym razem (i ten łańcuch musi być później zebrany). W przypadku symbolu, jest to w rzeczywistości ten sam symbol wszędzie. Mniej pracy dla alokatora pamięci, garbage collector, a nawet dla Ciebie (: jest szybszy do wpisania niż "")

Jeśli masz prosty jedno-wyrazowy ciąg znaków, który często pojawia się w Twoim kodzie i nie robisz z nim nic dziwnego( interpolacja, gsub, upcase itp.), to prawdopodobnie dobrym kandydatem jest symbol.

Jednakże, czy dotyczy to tylko tekstu, który jest używany jako część rzeczywistej logiki programu, takiej jak nazewnictwo, a nie tekstu, który otrzymuje się podczas rzeczywistego działania programu...takie jak tekst od Użytkownika / www itp?

Nie przychodzi mi do głowy żaden przypadek, w którym chciałbym zamienić dane z user / web na symbol(może poza analizowaniem opcji wiersza poleceń). GĹ ' Ăłwnie ze wzglÄ ™ du na konsekwencje (raz stworzone symbole ĺľyjä ... wiecznie).

Ponadto, wielu redaktorów zapewnia różne kolorowanie symboli, aby podświetlić je w kodzie. Spójrz na ten przykład

symbol vs ciąg

 35
Author: Sergio Tulentsev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-11 08:54:36

O ' Reilly jest jednym z najbardziej znanych i cenionych artystów na świecie. ]}

  • Jeśli zawartość (sekwencja znaków) obiektu jest ważna, użyj ciągu znaków.
  • Jeśli tożsamość obiektu jest ważna, użyj symbolu.

Symbole są zwykle używane jako klucze hashowe, ponieważ ważna jest tożsamość klucza. Symbole są również wymagane podczas przekazywania wiadomości przy użyciu pewnych metod, takich jak Object#send.

 11
Author: Todd A. Jacobs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-14 23:57:27

Implementacja Ruby zazwyczaj zawiera tabelę, w której przechowuje nazwy wszystkich klas, metod i zmiennych. Odnosi się do wymawiania nazwy metody przez pozycję w tabeli, unikając kosztownych porównań ciągów. Ale możesz również użyć tej tabeli i dodać do niej wartości: symbols.

Jeśli piszesz kod, który używa łańcuchów jako identyfikatorów, a nie dla ich zawartości tekstowej, rozważ symbole. Jeśli piszesz metodę, która oczekuje, że argument będzie "męski" lub "żeński", rozważ użycie :male i :female. Porównywanie dwóch symboli dla równości jest szybsze niż ciągi znaków (dlatego symbole tworzą dobre klucze skrótu).

 8
Author: steenslag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-13 08:24:38

Symbole są używane do nazywania rzeczy w języku: nazwy klas, nazwy metod itp. Są one bardzo podobne do ciągów, z wyjątkiem tego, że nigdy nie mogą być zbierane śmieci, a testowanie równości jest zoptymalizowane tak, aby było bardzo szybkie.

Implementacja Javy ma bardzo podobną funkcję, z tym, że nie jest dostępna do użytku w trybie runtime. Chodzi mi o to, że kiedy piszesz kod Javy w stylu obj.someMethod(4), Łańcuch "someMethod" jest konwertowany przez kompilator na symbol, który jest osadzony w wyszukiwarce tabela w .plik klasowy. Symbole te są jak "specjalne" ciągi, które nie są zbierane śmieci i które są bardzo szybkie do porównania dla równości. Jest to prawie identyczne z Rubim, z tym wyjątkiem, że Ruby pozwala na tworzenie nowych symboli w czasie wykonywania, podczas gdy Java zezwala na to tylko podczas kompilacji.

To jest tak jak tworzenie nowych metod -- Java pozwala na to w czasie kompilacji; Ruby pozwala na to w czasie wykonywania.

 5
Author: Rich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-17 10:38:28