Как преобразовать ActiveSupport:: SafeBuffer в String?

Я хочу получить объект String из ActiveSupport:: SafeBuffer. Метод to_s возвращает тот же тип ActiveSupport:: SafeBuffer. Только to_sym.to_s возвращает String, но это скорее хак. Здесь моя консоль играет:

irb(main):008:0> s = ActiveSupport::SafeBuffer.new("asdf")
# => "asdf"
irb(main):009:0> s.class
# => ActiveSupport::SafeBuffer
irb(main):010:0> s.to_s.class
# => ActiveSupport::SafeBuffer
irb(main):011:0> s.to_sym.to_s
# => "asdf"
irb(main):012:0> s.to_sym.to_s.class
# => String

Ответ 1

интерполировать его как строку:

irb(main):001:0> "#{ActiveSupport::SafeBuffer.new("asdf")}".class
=> String

Ответ 2

На самом деле существует метод для этого: String#to_str

buf = ActiveSupport::SafeBuffer.new("asdf")

str = buf.to_str #=> "asdf"
str.class        #=> String

String#to_str работает точно так же, как String#to_s: он возвращает получателя, при необходимости преобразуя его в String. Но в отличие от переопределенного ActiveSupport::SafeBuffer#to_s нет ActiveSupport::SafeBuffer#to_str, поэтому вызывается оригинальный метод.


Обратите внимание, что ActiveSupport::SafeBuffer является подклассом String:

s = ActiveSupport::SafeBuffer.new("asdf")
s.is_a? String
# => true

Поэтому обычно нет необходимости его конвертировать.

Ответ 3

У меня недостаточно репутации для комментариев, но я должен дополнить то, что иногда нужно преобразовать ActiveSupport::SafeBuffer в String.

Я встретил эту проблему при применении gsub объекта ActiveSupport::SafeBuffer.

s = ActiveSupport::SafeBuffer.new("asdf")
s.gsub(/a/) { puts $1.present? }

$1 всегда будет равным нулю. Вы должны сначала преобразовать s в String

s = ActiveSupport::SafeBuffer.new("asdf")
s.to_str.gsub(/a/) { puts $1.present? }

Это вернет правильный ответ. Даже s.to_s здесь бесполезно.