Рубиновый эквивалент Python `repr ()`? - PullRequest
0 голосов
/ 20 октября 2019

Существует ли Ruby-эквивалент метода repr в Python? Я хочу получить строковое представление любого данного объекта ruby, в котором перечислены все атрибуты, их значения и все методы.

Я определил следующий метод, но мне интересно, есть ли более канонический способделать это ...

def repr
  attrhash = {}
  instance_variables.sort.each {
    |v|
    attrhash[v] = instance_variable_get(v)
  }
  [ self, self.class.instance_methods.sort, attrhash ].to_s
end

В идеале, я бы не хотел включать этот метод в каждый класс, для которого мне нужны его repr -подобные данные, и мне интересноесли есть стандартный механизм ruby, чтобы получить эту информацию для любого данного объекта.

Ответы [ 3 ]

3 голосов
/ 20 октября 2019

В Ruby нет эквивалента __repr__ в Python. На первый взгляд, ближайшая вещь может казаться равной #inspect, из-за этих сходств:

Это обычно используется для отладки, […]

и

Возвращает строку, содержащую удобочитаемое представление obj .

Но есть важное отличие:

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

и

Для многих типов эта функция пытается вернуть строку, которая выдаст объект с тем же значением при передаче в eval()

Ruby's #inspect фокусируется на том, чтобы быть удобочитаемым , тогда как Python __repr__ пытается быть "eval() -round-trippable" (то есть eval(repr(e)) == e), другими словами, оно должно быть машиночитаемым .

3 голосов
/ 20 октября 2019

На основании полезных комментариев от jeremy04 и Jörg W Mittag я понимаю, что в Ruby нет ничего, что соответствует repr, и что я не могу использовать простой repr -подобный метод ввсе экземпляры классов без самоопыления class Object. Тем не менее, я понимаю, что если я просто сделаю repr автономной функцией, я смогу получить ту же функциональность, не применяя мартышки-патчи и выполняя repr(obj) вместо obj.repr всякий раз, когда мне нужна эта информация для данного объекта. Следующая автономная функция работает ...

def repr(obj)
  attrhash = {}
  obj.instance_variables.sort.each {
    |v|
    attrhash[v] = instance_variable_get(v)
  }
  {
    :string     => obj.inspect,
    :methods    => obj.class.instance_methods.sort,
    :attributes => attrhash
  }
end

У меня есть эта функция, возвращающая хеш вместо строки, чтобы я мог делать такие вещи:

repr(obj)[:attributes].

Я всегда могу сделать repr(obj).to_s, если мне нужна строка.

Кроме того, я могу превратить это в класс. Я оставлю это как упражнение для читателя. :)

1 голос
/ 20 октября 2019

inspect является ближайшим эквивалентом repr в Ruby, но он не показывает публичные методы.

Если вы ищете инструмент вместо: pry https://github.com/pry/pry

Команда ls делает именно то, что вы хотите. Вы также можете интегрировать pry в вашу консоль irb / rails.

В качестве альтернативы, вы можете использовать патч обезьяны class Object с вашим методом, но я чувствую, что это слишком экстремальный выбор, довольно много недостатков.

...