129 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			129 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								title: Ruby Symbols
							 | 
						|||
| 
								 | 
							
								localeTitle: Символы Ruby
							 | 
						|||
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								## Символы Ruby
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Символ выглядит как имя переменной, но имеет префикс двоеточия. Примеры -: action,: line\_items. Вам не нужно предварительно объявлять символ, и они гарантированно будут уникальными. Нет необходимости назначать какую-то ценность символу - Ruby позаботится об этом для вас. Ruby также гарантирует, что независимо от того, где он появляется в вашей программе, конкретный символ будет иметь такое же значение.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Кроме того, вы можете рассматривать двоеточие как «вещь с именем» так: id - это «вещь с именем id». Вы также можете думать о: id как о значении переменной id, а plain id - о значении переменной.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Для ex: Таким образом, если Fred является константой в одном контексте, метод в другом и класс в третьем, символ: Fred будет тем же самым объектом во всех трех контекстах.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```ruby
							 | 
						|||
| 
								 | 
							
								module One 
							 | 
						|||
| 
								 | 
							
								  class Fred 
							 | 
						|||
| 
								 | 
							
								  end 
							 | 
						|||
| 
								 | 
							
								  $f1 = :Fred 
							 | 
						|||
| 
								 | 
							
								 end 
							 | 
						|||
| 
								 | 
							
								 module Two 
							 | 
						|||
| 
								 | 
							
								  Fred = 1 
							 | 
						|||
| 
								 | 
							
								  $f2 = :Fred 
							 | 
						|||
| 
								 | 
							
								 end 
							 | 
						|||
| 
								 | 
							
								 def Fred() 
							 | 
						|||
| 
								 | 
							
								 end 
							 | 
						|||
| 
								 | 
							
								 $f3 = :Fred 
							 | 
						|||
| 
								 | 
							
								 $f1.object_id   #=> 2514190 
							 | 
						|||
| 
								 | 
							
								 $f2.object_id   #=> 2514190 
							 | 
						|||
| 
								 | 
							
								 $f3.object_id   #=> 2514190 
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## Работа с символами
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Вы можете распознать символ Ruby, потому что это будет слово, которое начинается с:.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								До сих пор мы рассматривали их как ключ в хеше (работа с хэшами в Ruby):
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```ruby
							 | 
						|||
| 
								 | 
							
								person = {:name => "Philip"} 
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Итак, первое, что мы можем сделать, это проверить Символ, чтобы узнать, какой класс он использует:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```ruby
							 | 
						|||
| 
								 | 
							
								:hello.class 
							 | 
						|||
| 
								 | 
							
								 => Symbol 
							 | 
						|||
| 
								 | 
							
								 
							 | 
						|||
| 
								 | 
							
								 "hello".class 
							 | 
						|||
| 
								 | 
							
								 => String 
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Таким образом, мы можем видеть, что символы и строки являются экземплярами двух разных объектов.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Вы можете вызвать струноподобные методы , такие как `upcase` , `downcase` и `capitalize` на Символов:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```ruby
							 | 
						|||
| 
								 | 
							
								:hello.upcase 
							 | 
						|||
| 
								 | 
							
								 => :HELLO 
							 | 
						|||
| 
								 | 
							
								 
							 | 
						|||
| 
								 | 
							
								 :HELLO.downcase 
							 | 
						|||
| 
								 | 
							
								 => :hello 
							 | 
						|||
| 
								 | 
							
								 
							 | 
						|||
| 
								 | 
							
								 :hello.capitalize 
							 | 
						|||
| 
								 | 
							
								 => :Hello 
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## Зачем использовать символ вместо строки?
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Итак, если символ - это просто неизменяемая строка, зачем вы его используете и почему в Ruby существует особое различие?
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## Символы неизменяемы
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Во-первых, одна из главных причин, как я упоминал выше, Символы неизменны. Непредвиденные ошибки могут появиться в вашем приложении, когда значение может измениться. Если вам необходимо убедиться, что значение объекта никогда не должно меняться, гораздо безопаснее использовать неизменяемый объект.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Однако, с учетом сказанного, можно сделать строку, неизменяемую в Ruby, вызвав метод `freeze` :
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```ruby
							 | 
						|||
| 
								 | 
							
								name = "Philip" 
							 | 
						|||
| 
								 | 
							
								 => "Philip" 
							 | 
						|||
| 
								 | 
							
								 
							 | 
						|||
| 
								 | 
							
								 name.freeze 
							 | 
						|||
| 
								 | 
							
								 => "Philip" 
							 | 
						|||
| 
								 | 
							
								 
							 | 
						|||
| 
								 | 
							
								 name << "Jim" 
							 | 
						|||
| 
								 | 
							
								 RuntimeError: can't modify frozen String 
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Как вы можете видеть в приведенном выше примере, как только вы вызываете метод замораживания в экземпляре String, вы больше не можете его изменять.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Так почему же вы использовали бы Символы вместо строк?
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### Символы лучше для производительности
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Вторая причина, по которой вы используете Symbol над String в определенных ситуациях, состоит в том, что символы намного лучше подходят для производительности.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Например:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```ruby
							 | 
						|||
| 
								 | 
							
								philip".object_id 
							 | 
						|||
| 
								 | 
							
								 => 70288511587360 
							 | 
						|||
| 
								 | 
							
								 "philip".object_id 
							 | 
						|||
| 
								 | 
							
								 => 70288504327720 
							 | 
						|||
| 
								 | 
							
								 
							 | 
						|||
| 
								 | 
							
								 :philip.object_id 
							 | 
						|||
| 
								 | 
							
								 => 539368 
							 | 
						|||
| 
								 | 
							
								 :philip.object_id 
							 | 
						|||
| 
								 | 
							
								 => 539368 
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Когда вы создаете два объекта String с одинаковым значением, эти два объекта рассматриваются как два разных объекта. Когда вы создаете Символ, ссылка на символ всегда будет использовать тот же объект.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Это намного лучше для производительности, потому что один и тот же объект String будет создан и уничтожен снова и снова, когда на самом деле один и тот же объект может быть повторно использован повторно.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### Методы общедоступного класса
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								all\_symbols => массив, чтобы переключить источник Возвращает массив всех символов, находящихся в настоящее время в таблице символов Ruby.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```ruby
							 | 
						|||
| 
								 | 
							
								Symbol.all_symbols.size    #=> 903 
							 | 
						|||
| 
								 | 
							
								 Symbol.all_symbols[1,20]   #=> [:floor, :ARGV, :Binding, :symlink, 
							 | 
						|||
| 
								 | 
							
								                                :chown, :EOFError, :$;, :String, 
							 | 
						|||
| 
								 | 
							
								                                :LOCK_SH, :"setuid?", :$<, 
							 | 
						|||
| 
								 | 
							
								                                :default_proc, :compact, :extend, 
							 | 
						|||
| 
								 | 
							
								                                :Tms, :getwd, :$=, :ThreadGroup, 
							 | 
						|||
| 
								 | 
							
								                                :wait2, :$>] 
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### Дополнительная информация:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								[Документация по Ruby Symbols](http://ruby-doc.org/core-2.5.1/Symbol.html)
							 |