-
Notifications
You must be signed in to change notification settings - Fork 455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
awesome print 2.0 #350
base: master
Are you sure you want to change the base?
awesome print 2.0 #350
Conversation
…ter formatters as they go. wip.
…pple, nobrainer) and relo external formatters to formatters/ext
sigh. this needs to be done way better.
it's out of date, and I don't have time to migrate and validate it. Ideally, these 3rd party lib formatters should be added by that lib, rather than awesome_print introspecting into the lib.
@base10 this is the PR i'm talking about :D thx |
@@ -6,6 +6,8 @@ module Colorize | |||
# Pick the color and apply it to the given string as necessary. | |||
#------------------------------------------------------------------------------ | |||
def colorize(str, type) | |||
# puts "[COLORIZING] - using #{options[:color][type]} for #{type}" if AwesomePrint.debug | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot some commented code here?
end | ||
|
||
# Main entry point to format an object. | ||
# register a new formatter.. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: extra period
# if that's not working, lets try discover the format via formattable? | ||
self.class.registered_formatters.each do |fmt| | ||
puts "[FIND] trying to use [#{fmt.first.to_s.greenish} - #{fmt.last.to_s.blue}] - core: #{fmt.last.core?}" if AwesomePrint.debug | ||
#{fmt.last.core?}" if AwesomePrint.debug |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commented code?
|
||
module AwesomePrint | ||
module Formatters | ||
class BigdecimalFormatter < BaseFormatter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious, should this retain the capitalization of BigDecimal
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 on retaining BigDecimal
capitalization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
] | ||
] | ||
] | ||
EOS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use tilde heredocs you can preserve indentation which'll make this a bit easier to read and modify later:
http://www.virtuouscode.com/2016/01/06/about-the-ruby-squiggly-heredoc-syntax/
it 'plain multiline' do
expect(@arr.ai(plain: true)).to eq <<~EOS.strip
[
[0] 1,
[1] :two,
[2] "three",
[3] [
[0] nil,
[1] [
[0] true,
[1] false
]
]
]
EOS
end
end | ||
|
||
def format(object) | ||
data = object.db_schema.inject({}) { |h, (prop, defn)| h.merge(prop => defn[:db_type]) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With isolated state like inject
or reduce
it may make more sense to use merge!
to avoid extra object allocations
require 'awesome_print/version' | ||
|
||
module AwesomePrint | ||
class << self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also use extend self
here instead of the singleton class trick.
require 'awesome_print/ext/action_view' | ||
# Class accessor to force colorized output (ex. forked subprocess where TERM | ||
# might be dumb). | ||
#--------------------------------------------------------------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably way overkill for this PR, but may make sense to look into YARDoc later as a standard documentation framework.
def format(object) | ||
@array = object | ||
|
||
if object.length.zero? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use object.empty?
here instead.
end | ||
hash | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might consider breaking this out into a method, as it's getting a bit long. Perhaps something like this?
def format(object)
if @options[:raw]
return Formatters::ObjectFormatter.new(@inspector).format(object)
end
if !defined?(::ActiveSupport::OrderedHash)
return Formatters::SimpleFormatter.new(@inspector).format(object.inspect)
end
object_dump = object.marshal_dump.first
data = if object_dump.class.column_names != object_dump.attributes.keys
object_dump.attributes
else
extract_column_values(object_dump)
end
data.merge!(details: object.details, messages: object.messages)
"#{object} " << Formatters::HashFormatter.new(@inspector).format(data)
end
def extract_column_values(object_dump)
object_dump
.class
.column_names
.each_with_object(::ActiveSupport::OrderedHash.new) do |column_name, hash|
if object_dump.has_attribute?(name) || object_dump.new_record?
value = object_dump.respond_to?(name) ? object_dump.send(name) : object_dump.read_attribute(name)
hash[name.to_sym] = value
end
end
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like @baweaver's method extraction and think I'd go a step further of extracting:
data = if object_dump.class.column_names != object_dump.attributes.keys
object_dump.attributes
else
extract_column_values(object_dump)
end
to its own method, returning data
.
hash[name.to_sym] = value | ||
end | ||
hash | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be worth considering an ActiveRecordHelper type module full of some of these types of methods, as they're repeated in a few places.
end | ||
|
||
def format_as_instance(object) | ||
data = (object.attributes || {}).sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use sort
instead of sort_by
here
data = (object.attributes || {}).sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c| | ||
hash[c[0].to_sym] = c[1] | ||
hash | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ActiveSupport has symbolize_keys
which you might find handy for this type of thing: https://apidock.com/rails/ActiveSupport/CoreExtensions/Hash/Keys/symbolize_keys
xml.gsub!(/>([^<]+)</) do |contents| | ||
contents = colorize($1, :trueclass) if contents && !contents.empty? | ||
">#{contents}<" | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be worth considering a Nokogiri helper for some of these features.
Depending on how much you want to look into this code it may also make sense to transfer the regex into named and documented constants to make it clearer what this code does.
end | ||
else # Prior to Ruby 1.9 the order of set values is unpredicatble. | ||
it 'plain multiline' do | ||
expect(@set.sort_by { |x| x.to_s }.ai(plain: true)).to eq(@arr.sort_by { |x| x.to_s }.ai(plain: true)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use sort_by(&:to_s)
to save a few characters
Let me know if you'd be interested in me going over anything in more detail, just a few suggestions and ideas for now. |
# simple formatter for now | ||
Formatters::ObjectFormatter.new(@inspector).format(object) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extraneous spaces here?
|
||
"#{object} " << Formatters::HashFormatter.new(@inspector).format(data) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extraneous space between block ends here?
"< #{colorize(object.superclass.to_s, :class)}", | ||
Formatters::HashFormatter.new(@inspector).format(data) | ||
].join(' ') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extraneous new line?
].join(' ') | ||
|
||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extraneous new line? (I see a lot of these below, too. If it's intentional 👍)
end | ||
|
||
def format | ||
# INSTANCE METHODS BELOW |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why the comment callout here and not with the other formatters.
#------------------------------------------------------------------------------ | ||
def should_be_limited? | ||
options[:limit] or (options[:limit].is_a?(Integer) and options[:limit] > 0) | ||
def self.formattable?(obj) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this obj argument?
end | ||
|
||
def format(object) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this argument required?
|
||
formatter_for :self | ||
|
||
def self.formattable?(object) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this object argument?
#------------------------------------------------------------------------------ | ||
# FIXME: this could be super fixed. | ||
# | ||
def convert_to_hash(object) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice to have like this:-
def convert_to_hash(object) | |
def convert_to_hash(object) |
def convert_to_hash(object)
return nil if !object.respond_to?(:to_hash) || object.method(:to_hash).arity != 0
hash = object.to_hash
return nil if !hash.respond_to?(:keys) || !hash.respond_to?('[]')
hash
end
New approach for awesomeprint -- this uses a factory pattern to register formatters as they go, etc.
feedback welcome!