Вход/Регистрация
Программирование на языке Ruby
вернуться

Фултон Хэл

Шрифт:

Вы можете реализовать метод

to_str
и самостоятельно, например, если хотите, чтобы строку можно было конкатенировать с числом:

class Numeric

 def to_str

to_s

 end

end

label = "Число " + 9 # "Число 9"

Аналогично обстоит дело и в отношении массивов. Для преобразования объекта в массив служит метод

to_a
, а метод
to_ary
вызывается, когда ожидается массив и ничего другого, например в случае множественного присваивания. Допустим, есть предложение такого вида:

а, b, с = x

Если

x
— массив из трех элементов, оно будет работать ожидаемым образом. Но если это не массив, интерпретатор попытается вызвать метод
to_ary
для преобразования в массив. В принципе это может быть даже синглетный метод (принадлежащий конкретному объекту). На само преобразование не налагается никаких ограничений, ниже приведен пример (нереалистичный), когда строка преобразуется в массив строк:

class String

 def to_ary

return self.split("")

 end

end

str = "UFO"

a, b, с = str # ["U", "F", "O"]

Метод

inspect
реализует другое соглашение. Отладчики, утилиты типа
irb
и метод отладочной печати
p
вызывают
inspect
, чтобы преобразовать объект к виду, пригодному для вывода на печать. Если вы хотите, чтобы во время отладки объект раскрывал свое внутреннее устройство, переопределите
inspect
.

Есть и еще одна ситуация, когда желательно выполнять такие преобразования «за кулисами». Пользователь языка ожидает, что

Fixnum
можно прибавить к
Float
, а комплексное число
Complex
разделить на рациональное. Но для проектировщика языка это проблема. Если метод
+
класса
Fixnum
получает аргумент типа
Float
, то что он должен с ним делать? Он знает лишь, как складывать значения типа
Fixnum
. Для решения проблемы в Ruby реализован механизм приведения типов
coerce
.

Когда оператор

+
(к примеру) получает аргумент, которого не понимает, он пытается привести вызывающий объект и аргумент к совместимым типам, а затем значения этих типов сложить. Общий принцип использования метода
coerce
прямолинеен:

class MyNumberSystem

 def +(other)

if other.kind_of?(MyNumberSystem)

result = some_calculation_between_self_and_other

MyNumberSystem.new(result)

else

n1, n2 = other.coerce(self)

n1 + n2

end

 end

end

Метод

coerce
возвращает массив из двух элементов: аргумент и вызывающий объект, приведенные к совместимым типам.

В примере выше мы полагались на то, что класс аргумента умеет как-то выполнять приведение. Будь мы законопослушными гражданами, реализовали бы приведение и в собственном классе, чтобы он мог работать с числами других видов. Для этого нужно знать, с какими типами мы можем работать напрямую, и приводить объект к одному из этих типов, когда возникает необходимость. Если мы сами не знаем, как это сделать, следует спросить у родителя:

def coerce(other)

 if other.kind_of?(Float)

return other, self.to_f

 elsif other.kind_of?(Integer)

return other, self.to_i

 else

super

 end

end

Конечно, чтобы этот пример работал, наш объект должен реализовывать методы

to_i
и
to_f
.

Метод

coerce
можно использовать для реализации автоматического преобразования строк в числа, как это делается в языке Perl:

class String

 def coerce(n)

if self['.']

[n, Float(self)]

else

[n, Integer(self)]

end

 end

end

x = 1 + "23" # 24

y = 23 * "1.23" # 29.29

Впрочем, поступать так необязательно. Однако мы настоятельно рекомендуем реализовывать метод

coerce
при разработке разного рода числовых классов.

  • Читать дальше
  • 1
  • ...
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: