Есть ли встроенный в Ruby класс или модуль (кроме String), имеющий метод #to_str? - PullRequest
3 голосов
/ 22 сентября 2019

Для некоторого тестирования я ищу встроенный класс или модуль Ruby (кроме String), который имеет метод # to_str.

(я знаю, что у многих есть метод #to_s, но это не такчто я ищу.)

Я просмотрел документы и не могу найти ничего подобного.

Ответы [ 2 ]

7 голосов
/ 22 сентября 2019

Самый простой способ - спросить у самой Руби:

ObjectSpace.
  each_object(Module).
  select {|mod| mod.instance_methods(false).include?(:to_str) } - 
    [String]
#=> [NameError::message]

Итак, оказывается, единственный другой класс, который определяет to_str, это внутренний класс реализации внутри NameError.Что имеет смысл, на самом деле, в Ruby не так много объектов, которые являются строками, но не являются экземплярами String.

Я бы ожидал библиотеку Ropes (если такая вещь существует) реализовать to_str, например.

1 голос
/ 22 сентября 2019

Это не отвечает на вопрос, существует ли какой-либо класс, реализующий метод #to_str.Скорее, этот ответ сфокусирован на:

Для некоторого тестирования я ищу встроенный класс или модуль Ruby (кроме String), который имеет метод # to_str.

Вы можете создать временный класс для целей тестирования, который перенаправляет все вызовы на внутреннюю строку.

require 'delegate'

# create an anonymous class inheriting from DelegateClass(String)
my_string_class = Class.new(DelegateClass(String))
my_string       = my_string_class.new("Hello World!")

my_string.is_a?(String)     #=> false
"Hello World!" == my_string #=> true

Причину, по которой приведенное выше сравнение возвращает true, можно найти в String документация .

str == obj → true или false

Equality - возвращает значение str == obj, аналогичное Object#==.

Если obj не является экземпляром String , но отвечает на to_str, тогда две строки сравниваются с использованием obj.==.

В противном случае возвращает аналогично #eql?, сравнение длины и содержимого.

Вы также можете пропустить создание анонимного класса и использовать вместо него SimpleDelegator .

my_string = SimpleDelegator.new("Hello World!")

Для получения дополнительной информации о делегаторах посмотрите документацию .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...