к s и к (ул. и я/к/к H и к инт/до Ары/хэша) в Ruby
Я изучаю Ruby, и я видел несколько методов, которые меня немного смущают, особенно to_s
vs to_str
(и точно так же,to_i
/to_int
,to_a
/to_ary
,& to_h
/to_hash
). То, что я прочитал, объясняет, что более короткая форма (например,to_s
) предназначены для явных преобразований, а более длинная форма - для неявных преобразований.
Я действительно не понимаю, как to_str
будет фактически использоваться. Будет ли что-то другое, чем строка, когда-либо определять to_str
? Вы можете дать практическое применение этому методу?
2 ответа:
обратите внимание, что все это относится к каждой паре "коротких" (например,
to_s
/to_i
/to_a
/to_h
) и "длинные" (например,to_str
/to_int
/to_ary
/to_hash
) методы принуждения в Ruby (для их соответствующих типов), поскольку все они имеют одинаковую семантику.
они имеют разные значения. Вы не должны реализовывать
to_str
если ваш объект действия как строка, а не просто быть представимое строкой. Единственный основной класс это реализуетto_str
сама строка.С Программирования Ruby (цитата из этот блог, который стоит прочитать всем):
[
to_i
иto_s
] не особенно строгие: если объект имеет какое-то приличное представление в виде строки, например, он, вероятно, будет иметьto_s
метод... [to_int
иto_str
] являются строгими функциями преобразования: вы реализуете их только в том случае, если [ваш] объект может быть естественным используется в каждом месте, где может использоваться строка или целое число.старые рубиновые документы из кирки говорит:
в отличие от
to_s
, который поддерживается почти всеми классами,to_str
обычно реализуется только теми классами, которые действуют как строки.например, в дополнение к целое, и Float & цифровой реализовать
to_int
(to_i
' s эквивалентto_str
) потому что оба они могут легко заменить целое число (все они на самом деле числа). Если ваш класс не имеет аналогичной тесной связи со строкой, вы не должны реализовыватьto_str
.
чтобы понять, если вы должны использовать/реализовать
to_s
/to_str
, давайте рассмотрим некоторые примеры. Это показательно рассмотреть когда эти методы терпят неудачу.1.to_s # returns "1" Object.new.to_s # returns "#<Object:0x4932990>" 1.to_str # raises NoMethodError Object.new.to_str # raises NoMethodError
как видим,
to_s
С удовольствием включаю любой объект в строку. С другой стороны,to_str
выдает ошибку, когда его параметр не выглядит как струна.
теперь давайте посмотрим на
Array#join
.[1,2].join(',') # returns "1,2" [1,2].join(3) # fails, the argument does not look like a valid separator.
это полезно это
Array#join
преобразует в строку элементы в массиве (независимо от того, что они на самом деле), прежде чем присоединиться к ним, так чтоArray#join
звонкиto_s
на них.однако разделитель должен быть строкой -- кто-то звонит
[1,2].join(3)
скорее всего, делает ошибку. Вот почемуArray#join
звонкиto_str
на сепаратор.
тот же принцип, по-видимому, применим и к другим методам. Рассмотрим
to_a
/to_ary
на a хэш:{1,2}.to_a # returns [[1, 2]], an array that describes the hash {1,2}.to_ary # fails, because a hash is not really an array.
в общем, вот как я это вижу:
- вызов
to_s
чтобы получить строку, описывающую объект.- вызов
to_str
чтобы убедиться, что объект действительно выступает как струна.- реализовать
to_s
когда вы можете построить строку, которая описывает объект.- реализовать
to_str
когда ваш объект может полностью вести себя как струна.я думаю, что случай, когда вы могли бы реализовать
to_str
вы сами, может быть,ColoredString
class -- строка, к которой прикреплен цвет. Если вам кажется ясным, что передача цветной запятой вjoin
это не ошибка и в результате"1,2"
(даже если эта строка не будет окрашена), то do реализоватьto_str
на ColoredString.