переопределить to_s, сохраняя вывод проверки - PullRequest
3 голосов
/ 02 марта 2012

Я переопределяю метод to_s, чтобы получить симпатичный вывод при использовании пут, но в то же время я, похоже, теряю способность осматривать объектЕсть ли способ получить нормальный вывод inspect при переопределении to_s?

class Person
  attr_accessor :first, :last, :birthdate
  def initialize(first=nil, last=nil, birthdate=nil)
    @first, @last, @birthdate = first, last, birthdate
  end
  def age
    if birthdate
      Time.now.year-birthdate
    else
      0
    end
  end
  def to_s
    "#{@first} #{@last} (#{age})"
  end
end

me = Person.new("Peter", "Marien", 1962)
p me  >>Peter Marien (50)
p me.inspect  >>"Peter Marien (50)"

#Need #<Person:0x1ec2550 @first="Peter", @last="Marien", @birthdate=1962>

Ответы [ 4 ]

4 голосов
/ 02 марта 2012

Документация Ruby четко заявляет , что по умолчанию inspect использует to_s в качестве вывода.

Если вам не нужен адрес объекта, вы можете предоставитьдля собственного осмотра, чтобы иметь почти такое же поведение:

class Person
  def inspect
    vars = self.instance_variables.
      map{|v| "#{v}=#{instance_variable_get(v).inspect}"}.join(", ")
    "<#{self.class}: #{vars}>"
  end
end

Но вы также можете установить гем под названием awesome_print, который даст очень хороший результат.Сначала в консоли:

$ gem install awesome_print

, затем в irb или в вашем скрипте:

require 'awesome_print'
ap Person.new("John")

Существует также встроенная библиотека pp, которая имеет аналогичное назначение.Тем не менее, он не защищен (по крайней мере в Ruby 1.9.2-p290) от переопределения to_s.

Быстрый пример pp:

require 'pp'
pp Person.new("John")
0 голосов
/ 02 марта 2012

Перри, здесь одна из многих комбинаций, которые я пытался заставить работать псевдоним или alias_method. Если вы считаете, что это работает, вы можете отправить рабочий фрагмент?

class Person
  attr_accessor :first, :last, :birthdate
  def initialize(first=nil, last=nil, birthdate=nil)
    @first, @last, @birthdate = first, last, birthdate
  end

  alias old_to_s to_s
  def inspect
    old_to_s
  end
  def to_s
    "#{@first} #{@last}"
  end

end

me = Person.new("Peter")
p me         #-->#<Person:0x1da26b8>
p me.inspect #-->"#<Person:0x1da26b8>"
0 голосов
/ 02 марта 2012

Здесь решение Александера, первая буква p должна дать переопределенный to_s, но нет, вы должны явно вызвать to_s, как во второй букве p, чтобы получить желаемый результат.Я также не уверен, что эта проверка даст тот же результат, что и оригинал с более сложными объектами, я попробую это дома.Кто-нибудь еще лучше выстрелил?Я знаю о драгоценном камне awesome_print, но ИМХО для чего-то базового вам не нужно включать драгоценные камни.

class Person

  def initialize(first=nil, last=nil, birthdate=nil) 
    @first, @last, @birthdate = first, last, birthdate 
  end 

  # New implementation of to_s 
  def to_s 
    "#{@first} #{@last}" 
  end

  def inspect 
    vars = self.instance_variables. 
      map{|v| "#{v}=#{instance_variable_get(v).inspect}"}.join(", ") 
    "<#{self.class}: #{vars}>" 
  end 

end 

me = Person.new("John")
p me         #--><Person: @first="John", @last=nil, @birthdate=nil>
p me.to_s    #-->"John "
p me.inspect #-->"<Person: @first=\"John\", @last=nil, @birthdate=nil>"

Редактировать: я только что попробовал awesome_print и мне приятно, я боялся, что должениспользовать IRB, чтобы использовать его, но это не так, я запускаю свои скрипты в своем редакторе, а именно:

require 'awesome_print'
ap me --> 
#<Person:0x027efe20
    @birthdate = nil,
    @first = "John",
    @last = nil
>

Редактировать, используя pretty_print, как предложено Александром, не мешает переопределенным to_s

require 'PP'
class Person

  def initialize(first=nil, last=nil, birthdate=nil) 
    @first, @last, @birthdate = first, last, birthdate 
  end 

  # New implementation of to_s 
  def to_s 
    "#{@first} #{@last}" 
  end
end 

me = Person.new("John")
pp me                   #--> <Person: @first="John", @last=nil, @birthdate=nil>
warn me.pretty_inspect  #--> <Person: @first="John", @last=nil, @birthdate=nil>
0 голосов
/ 02 марта 2012

Я полагаю, что по умолчанию inspect использует метод to_s.

Однако вы также можете переопределить inspect, включая наложение на него старого метода to_s перед переопределением.

...