к 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вы сами, может быть,ColoredStringclass -- строка, к которой прикреплен цвет. Если вам кажется ясным, что передача цветной запятой вjoinэто не ошибка и в результате"1,2"(даже если эта строка не будет окрашена), то do реализоватьto_strна ColoredString.