Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
implement ActiveRecord::Base#pretty_print #15172
AR::B has long been lacking pretty print support. I submitted this patch some years ago (pre-github), attempting again.
(same as #inspect)
I recently submitted #18353 and have finally tracked down the cause of this issue to this commit. It turns out that while this feature is actually awesome, it also breaks some expected Ruby behavior in ActiveRecord classes. The inspect method in all ActiveRecord models is now effectively ignored in Rails 4.2 going forward.
Here is an example:
class Foo < ActiveRecord::Base def initialize(a=1,b=2) @a = a @b = b end end Rails(4.1) Foo.new #=> "#<Foo:0x0300c868 a: 1, b: 2 >" Rails(4.2) Foo.new #=> "#<Foo:0x0300c868 a: 1 b: 2>"
This is when the feature looks great and works as expected.
However consider this case:
class Foo < ActiveRecord::Base def initialize(a=1,b=2) @a = a @b = b end def inspect "Foo is awesome" end end Rails(4.1) Foo.new #=> "Foo is awesome" Rails(4.2) Foo.new #=> "#<Foo:0x0300c868 a: 1 b: 2>"
Here the user defined inspect method is completely ignored! Which IMO is undesirable. What do you guys think?
Yes, pry uses PP. But it first of all looks at the object's inspect method. Which is the expected Ruby behavior. With this change, we completely ignore the user defined inspect methods.
It seems to me that instead of defining pretty_print, you should be overriding the pp_object method which is the failsafe in Ruby in order to achieve both cases. This is my 2 cents.
And FYI, I'm the one that opened pry/pry#1337 and we concluded that this is a Rails issue.
defining #pretty_print is the standard and intended way of implementing pretty-print capability. pp_object is not related to anything here.
this is not correct, per the discussion at pry/pry#1337 : "PP preferentially uses pretty_print over inspect"
I don't see anything over there that suggests this. rf- says "If you want to customize the output for your models, you can either
I think you are completely missing my point. The Ruby language uses the inspect method to "make better representation of user defined classes". It's a Ruby fundamental. The
With this current implementation, you completely ignore the
Consider an ActiveRecord model with 2000 attributes. If I only care about one attribute, then I would define that model's inspect method. Currently, with this implementation, you are forcing the user to see every single attribute whether they care about seeing it or not without any regard for the already defined inspect methods.
Hope this makes my point clear.
although pretty-print does fall back to inspect for objects that do not define their own pretty-printing, the implementations of inspect and pp are separate, and no other implementation of pretty printing has anything to do with #inspect (that I am aware of or have ever seen).
activerecord's pretty print implementation could in theory check if a subclass of AR::B has overridden #inspect and use that instead of its own pretty-print if so, but it seems questionable to me that this is better behavior. if PP is being used (as pry does), then a pretty-printed representation is what should be returned - not the more concise result of #inspect.
it's worth noting that this is not an issue particular to activerecord: if you subclass any other class, apart from Object, that implements pretty-printing - such as Array, Hash, many other core classes, as well as many third party libraries - pry (and anything else that uses pp) will ignore your inspect method:
FWIW, I think I disagree: I can't think of any instance where PP intends to be more informative than the corresponding
I'd thus consider the custom-
I think we should do this: enhance our own
if that is the way to go, it looks like it is simple enough to implement
def pretty_print(pp) if self.class.instance_method(:inspect).owner < ActiveRecord::Base pp.text inspect else [current implementation] end end