Символы в рубине - PullRequest
       7

Символы в рубине

4 голосов
/ 14 июля 2011

Я не знаю, понимаю ли я, что такое символ. Я прочитал следующее в разных местах:

  • Символы являются неизменяемыми, что означает, что содержимое не изменится после их инициализации. Это означает, что объект может иметь много ссылок на него, так как содержимое не может измениться.
  • Используйте символы для идентификации и строки, где содержание имеет значение.
  • Объект-символ создается только один раз и существует до тех пор, пока выполняется процесс.
  • О таблице символов

Я не понимаю этих фраз. Наконец, я не понимаю, что такое символьный объект. Является ли :name символьным объектом или :name просто ссылкой на символьный объект где-то еще?

Ответы [ 6 ]

4 голосов
/ 14 июля 2011

Эта цитата из книги ' Красноречивый Ruby ' помогла мне понять символы, в книге есть целая глава, посвященная строкам и символам, которая также очень хороша.

Ответ таков:что мы склонны использовать строки символов в нашем коде для двух довольно разных целей: первое и наиболее очевидное использование для строк - это хранение некоторых данных, которые мы обрабатываем.Прочитайте в этой книге объекты из базы данных, и вы, скорее всего, будете полны строковых данных, таких как название книги, имя автора и фактический текст.

Второй способ, который мы используемСтроки символов должны представлять вещи в наших программах, такие как желание найти все записи в таблице.Главное в нашем примере Book ActiveRecord - это то, что ActiveRecord может распознать его, когда видит, - код должен знать, какие записи возвращать, и: all - это флаг, который говорит, что должен возвращать все.Хорошая вещь в использовании чего-то вроде: все для такого рода «отстаивания» долга состоит в том, что оно также имеет смысл для людей: у вас гораздо больше шансов узнать, что: все означает, когда вы сталкиваетесь с этим, чем 0, или -1 или даже (боже упаси!) 0x29ef.

Эти два варианта используются для строк символов - для обычных задач обработки данных, с одной стороны, и для внутренних, символических заданий типа маркера, с другой - делают оченьразличные требования к объектам.Если вы обрабатываете данные, вам понадобится весь спектр инструментов для работы со строками: вам могут понадобиться первые десять символов заголовка или вы хотите узнать его длину или посмотреть, соответствует ли оно некоторому регулярному выражению.С другой стороны, если вы используете некоторые символы для обозначения чего-то в вашем коде, вы, вероятно, не очень заинтересованы в том, чтобы возиться с реальными символами.Вместо этого во втором случае вам просто нужно знать, является ли эта вещь флагом, который говорит вам найти все записи или только первую запись.В основном, когда вы хотите, чтобы некоторые персонажи что-то обозначали, вам просто нужно знать, является ли это так же, быстро и надежно.
3 голосов
/ 14 июля 2011

Возможно, этот сеанс IRB может немного прояснить ситуацию:

irb(main):001:0> "First".object_id
=> 23849064
irb(main):002:0> "First".object_id
=> 23842248
irb(main):003:0> "First".object_id
=> 23835432
irb(main):004:0> "First".object_id
=> 23828616
irb(main):005:0> :First.object_id
=> 301892
irb(main):006:0> :First.object_id
=> 301892
irb(main):007:0> :First.object_id
=> 301892
irb(main):008:0> :First.object_id
=> 301892
irb(main):009:0>

Представьте, что метод object_id похож на адрес объекта. Как видите, строка «Первая» каждый раз имеет новый адрес (то есть каждый раз создается новый объект), в то время как символ не меняется. Возможно, вы могли бы связать символы с синглетами (как в шаблоне синглтона, а не в метапрограммировании), для более легкого понимания.

2 голосов
/ 14 июля 2011

Вы можете рассматривать символы как своего рода константы, но они не содержат фактического значения. На языках без символов вы можете сделать что-то подобное для удобства:

const BLUE = 1
const GREEN = 2

my_color = GREEN

...


if (my_color == GREEN)

В Ruby вы можете использовать символы для этого:

my_color = :green

...

if my_color == :green

Это более эффективно, поскольку символ - это просто символ. Он не хранит значения или что-либо еще, поэтому вам не нужно их инициализировать. Я не уверен, как символы обрабатываются в интерпретаторе Ruby, но я не думаю, что это актуально для любого начинающего программиста ruby.

Хорошее руководство можно найти здесь: http://www.troubleshooters.com/codecorn/ruby/symbols.htm

1 голос
/ 24 октября 2013

Я думаю, что символы лучше всего объяснить с помощью прецедентов.

Для создания констант они более выразительны, чем целые.

def rgb(color_symbol)
  return nil unless color_symbol.is_a? Symbol
  case color_symbol
  when :red;   { r: 255, g: 0, b: 0 }
  when :green; { r: 0, g: 255, b: 0 }
  when :blue;  { r: 0, g: 0, b: 255 }
  else; { r: 0, g: 0, b: 0 }
  end
end

p rgb(color_symbol= :red)

более читабельно, чем

def rgb(color_number)
  return nil unless color_number.is_a? Fixnum
  case color_number
  when 1; { r: 255, g: 0, b: 0 }
  when 2; { r: 0, g: 255, b: 0 }
  when 3; { r: 0, g: 0, b: 255 }
  else; { r: 0, g: 0, b: 0 }
  end
end

p rgb(color_number= 2)

Для сравнения в условных выражениях символы просто сравниваются по их уникальному адресу, поэтому они более эффективны, чем строки, которые сравниваются по длине, а затем по каждому символу.

def rgb(color_string)
  return nil unless color_string.is_a? String
  case color_string
  when "red";   { r: 255, g: 0, b: 0 }
  when "green"; { r: 0, g: 255, b: 0 }
  when "blue";  { r: 0, g: 0, b: 255 }
  else; { r: 0, g: 0, b: 0 }
  end
end

p rgb(color_string= "blue")

Это будет менее эффективно, чем использование символов.

0 голосов
/ 24 октября 2013

A Symbol Экземпляр - это упорядоченный набор символов. Экземпляр String - это контейнер для символов, место, которое может содержать любую последовательность символов.

0 голосов
/ 14 июля 2011

Эта статья также может представлять интерес http://www.robertsosinski.com/2009/01/11/the-difference-between-ruby-symbols-and-strings/, поскольку она помогла мне понять, чем символы отличаются от строк.

...