awesome_print 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ 1.0.2
2
+ - Added formatting of Mongoid documents (Adam Doppelt)
3
+ - ActiveRecord objects display attributes only. Use :raw => true to display the entire object
4
+ - ActiveSupport::Date objects get formatted as regular Date
5
+ - Rails.logger.ap colorizes output based on ActiveSupport::LogSubscriber.colorize_logging (default is true)
6
+ - Improved formatting of methods array
7
+
1
8
  1.0.1
2
9
  - Updated repo tags for Rubygems.org
3
10
 
data/README.md CHANGED
@@ -229,7 +229,7 @@ Supported color names:
229
229
 
230
230
  ### IRB integration ###
231
231
  To use awesome_print as default formatter in irb and Rails console add the following
232
- lines into your ~/.irbrc file:
232
+ code to your ~/.irbrc file:
233
233
 
234
234
  require "rubygems"
235
235
  require "awesome_print"
@@ -248,6 +248,15 @@ lines into your ~/.irbrc file:
248
248
  end.new
249
249
  end
250
250
 
251
+ ### PRY integration ###
252
+ If you miss awesome_print's way of formatting output, here's how you can use it in place
253
+ of the formatting which comes with pry. Add the following code to your ~/.pryrc:
254
+
255
+ require "rubygems"
256
+ require "awesome_print"
257
+
258
+ Pry.print = proc { |output, value| output.puts value.ai }
259
+
251
260
  ### Logger Convenience Method ###
252
261
  awesome_print adds the 'ap' method to the Logger and ActiveSupport::BufferedLogger classes
253
262
  letting you call:
@@ -266,7 +275,8 @@ in the custom defaults (see below). You can also override on a per call basis wi
266
275
  awesome_print adds the 'ap' method to the ActionView::Base class making it available
267
276
  within Rails templates. For example:
268
277
 
269
- <%= ap @accounts.first %>
278
+ <%= ap @accounts.first %> # ERB
279
+ != ap @accounts.first # HAML
270
280
 
271
281
  With other web frameworks (ex: in Sinatra templates) you can explicitly request HTML
272
282
  formatting:
@@ -23,7 +23,7 @@ unless defined?(AwesomePrint)
23
23
  require File.dirname(__FILE__) + "/awesome_print/ext/active_support" if defined?(ActiveSupport) || (defined?(IRB) && ENV['RAILS_ENV'])
24
24
 
25
25
  # Load remaining extensions.
26
- require File.dirname(__FILE__) + "/awesome_print/ext/action_view" if defined?(ActionView)
26
+ require File.dirname(__FILE__) + "/awesome_print/ext/action_view" if defined?(ActionView::Base)
27
27
  require File.dirname(__FILE__) + "/awesome_print/ext/mongo_mapper" if defined?(MongoMapper)
28
28
  require File.dirname(__FILE__) + "/awesome_print/ext/mongoid" if defined?(Mongoid)
29
29
  require File.dirname(__FILE__) + "/awesome_print/ext/nokogiri" if defined?(Nokogiri)
@@ -4,14 +4,19 @@
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
5
  #------------------------------------------------------------------------------
6
6
  class Class #:nodoc:
7
+ #
8
+ # Intercept methods below to inject @__awesome_print__ instance variable
9
+ # so we know it is the *methods* array when formatting an array.
10
+ #
7
11
  # Remaining public/private etc. '_methods' are handled in core_ext/object.rb.
12
+ #
8
13
  %w(instance_methods private_instance_methods protected_instance_methods public_instance_methods).each do |name|
9
14
  original_method = instance_method(name)
10
15
 
11
16
  define_method name do |*args|
12
17
  methods = original_method.bind(self).call(*args)
13
- methods.instance_variable_set('@__awesome_methods__', self) # Evil?!
14
- methods.sort!
18
+ methods.instance_variable_set('@__awesome_methods__', self)
19
+ methods
15
20
  end
16
21
  end
17
22
  end
@@ -17,4 +17,4 @@ module AwesomePrint
17
17
  end
18
18
 
19
19
  Logger.send(:include, AwesomePrint::Logger)
20
- ActiveSupport::BufferedLogger.send(:include, AwesomePrint::Logger) if defined?(::ActiveSupport::BufferedLogger)
20
+ ActiveSupport::BufferedLogger.send(:include, AwesomePrint::Logger) if defined?(ActiveSupport::BufferedLogger)
@@ -4,14 +4,19 @@
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
5
  #------------------------------------------------------------------------------
6
6
  class Object #:nodoc:
7
+ #
8
+ # Intercept methods below to inject @__awesome_print__ instance variable
9
+ # so we know it is the *methods* array when formatting an array.
10
+ #
7
11
  # Remaining instance '_methods' are handled in core_ext/class.rb.
12
+ #
8
13
  %w(methods private_methods protected_methods public_methods singleton_methods).each do |name|
9
14
  original_method = instance_method(name)
10
15
 
11
16
  define_method name do |*args|
12
17
  methods = original_method.bind(self).call(*args)
13
- methods.instance_variable_set('@__awesome_methods__', self) # Evil?!
14
- methods.sort!
18
+ methods.instance_variable_set('@__awesome_methods__', self)
19
+ methods
15
20
  end
16
21
  end
17
22
  end
@@ -15,4 +15,4 @@ module AwesomePrint
15
15
  end
16
16
  end
17
17
 
18
- ActionView::Base.send(:include, AwesomePrint::ActionView) if defined?(ActionView)
18
+ ActionView::Base.send(:include, AwesomePrint::ActionView)
@@ -15,7 +15,11 @@ module AwesomePrint
15
15
  #------------------------------------------------------------------------------
16
16
  def cast_with_active_record(object, type)
17
17
  cast = cast_without_active_record(object, type)
18
- if defined?(::ActiveRecord) && object.is_a?(Class) && object.ancestors.include?(::ActiveRecord::Base)
18
+ return cast if !defined?(::ActiveRecord)
19
+
20
+ if object.is_a?(::ActiveRecord::Base)
21
+ cast = :active_record_instance
22
+ elsif object.is_a?(Class) && object.ancestors.include?(::ActiveRecord::Base)
19
23
  cast = :active_record_class
20
24
  end
21
25
  cast
@@ -23,6 +27,26 @@ module AwesomePrint
23
27
 
24
28
  private
25
29
 
30
+ # Format ActiveRecord instance object.
31
+ #
32
+ # NOTE: by default only instance attributes (i.e. columns) are shown. To format
33
+ # ActiveRecord instance as regular object showing its instance variables and
34
+ # accessors use :raw => true option:
35
+ #
36
+ # ap record, :raw => true
37
+ #
38
+ #------------------------------------------------------------------------------
39
+ def awesome_active_record_instance(object)
40
+ return object.inspect if !defined?(::ActiveSupport::OrderedHash)
41
+ return awesome_object(object) if @options[:raw]
42
+
43
+ data = object.class.column_names.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
44
+ hash[name.to_sym] = object.send(name) if object.has_attribute?(name) || object.new_record?
45
+ hash
46
+ end
47
+ "#{object} " << awesome_hash(data)
48
+ end
49
+
26
50
  # Format ActiveRecord class object.
27
51
  #------------------------------------------------------------------------------
28
52
  def awesome_active_record_class(object)
@@ -14,7 +14,7 @@ module AwesomePrint
14
14
  def cast_with_active_support(object, type)
15
15
  cast = cast_without_active_support(object, type)
16
16
  if defined?(::ActiveSupport) && defined?(::HashWithIndifferentAccess)
17
- if object.is_a?(::ActiveSupport::TimeWithZone)
17
+ if object.is_a?(::ActiveSupport::TimeWithZone) || object.is_a?(::Date)
18
18
  cast = :active_support_time
19
19
  elsif object.is_a?(::HashWithIndifferentAccess)
20
20
  cast = :hash_with_indifferent_access
@@ -38,3 +38,10 @@ module AwesomePrint
38
38
  end
39
39
 
40
40
  AwesomePrint::Formatter.send(:include, AwesomePrint::ActiveSupport)
41
+ #
42
+ # Colorize Rails logs.
43
+ #
44
+ if defined?(ActiveSupport::LogSubscriber)
45
+ AwesomePrint.force_colors! ActiveSupport::LogSubscriber.colorize_logging
46
+ end
47
+
@@ -15,8 +15,14 @@ module AwesomePrint
15
15
  #------------------------------------------------------------------------------
16
16
  def cast_with_mongoid(object, type)
17
17
  cast = cast_without_mongoid(object, type)
18
- if defined?(::Mongoid::Document) && object.is_a?(Class) && object.ancestors.include?(::Mongoid::Document)
19
- cast = :mongoid_class
18
+ if defined?(::Mongoid::Document)
19
+ if object.is_a?(Class) && object.ancestors.include?(::Mongoid::Document)
20
+ cast = :mongoid_class
21
+ elsif object.class.ancestors.include?(::Mongoid::Document)
22
+ cast = :mongoid_document
23
+ elsif object.is_a?(::BSON::ObjectId)
24
+ cast = :mongoid_bson_id
25
+ end
20
26
  end
21
27
  cast
22
28
  end
@@ -26,13 +32,33 @@ module AwesomePrint
26
32
  def awesome_mongoid_class(object)
27
33
  return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:fields)
28
34
 
29
- data = object.fields.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
30
- hash[c[1].name] = (c[1].type || "undefined").to_s.underscore.intern
31
- # hash[c[1].name] = (c[1].type || "undefined").to_s.underscore.intern rescue c[1].type
35
+ data = object.fields.sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
36
+ hash[c[1].name.to_sym] = (c[1].type || "undefined").to_s.underscore.intern
32
37
  hash
33
38
  end
34
39
  "class #{object} < #{object.superclass} " << awesome_hash(data)
35
40
  end
41
+
42
+ # Format Mongoid Document object.
43
+ #------------------------------------------------------------------------------
44
+ def awesome_mongoid_document(object)
45
+ return object.inspect if !defined?(::ActiveSupport::OrderedHash)
46
+
47
+ data = object.attributes.sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
48
+ hash[c[0].to_sym] = c[1]
49
+ hash
50
+ end
51
+ if !object.errors.empty?
52
+ data = {:errors => object.errors, :attributes => data}
53
+ end
54
+ "#{object} #{awesome_hash(data)}"
55
+ end
56
+
57
+ # Format BSON::ObjectId
58
+ #------------------------------------------------------------------------------
59
+ def awesome_mongoid_bson_id(object)
60
+ object.inspect
61
+ end
36
62
  end
37
63
  end
38
64
 
@@ -25,12 +25,13 @@ module AwesomePrint
25
25
  awesome = if core_class != :self
26
26
  send(:"awesome_#{core_class}", object) # Core formatters.
27
27
  else
28
- awesome_self(object, type) # Catch all that falls back on object.inspect.
28
+ awesome_self(object, type) # Catch all that falls back to object.inspect.
29
29
  end
30
30
  @options[:html] ? "<pre>#{awesome}</pre>" : awesome
31
31
  end
32
32
 
33
- # Hook this when adding custom formatters.
33
+ # Hook this when adding custom formatters. Check out lib/awesome_print/ext
34
+ # directory for custom formatters that ship with awesome_print.
34
35
  #------------------------------------------------------------------------------
35
36
  def cast(object, type)
36
37
  CORE.grep(type)[0] || :self
@@ -212,17 +213,20 @@ module AwesomePrint
212
213
  # Format object.methods array.
213
214
  #------------------------------------------------------------------------------
214
215
  def methods_array(a)
216
+ a.sort! { |x, y| x.to_s <=> y.to_s } # Can't simply a.sort! because of o.methods << [ :blah ]
215
217
  object = a.instance_variable_get('@__awesome_methods__')
216
218
  tuples = a.map do |name|
217
- tuple = if object.respond_to?(name, true) # Is this a regular method?
218
- the_method = object.method(name) rescue nil # Avoid potential ArgumentError if object#method is overridden.
219
- if the_method && the_method.respond_to?(:arity) # Is this original object#method?
220
- method_tuple(the_method) # Yes, we are good.
219
+ if name.is_a?(Symbol) || name.is_a?(String) # Ignore garbage, ex. 42.methods << [ :blah ]
220
+ tuple = if object.respond_to?(name, true) # Is this a regular method?
221
+ the_method = object.method(name) rescue nil # Avoid potential ArgumentError if object#method is overridden.
222
+ if the_method && the_method.respond_to?(:arity) # Is this original object#method?
223
+ method_tuple(the_method) # Yes, we are good.
224
+ end
225
+ elsif object.respond_to?(:instance_method) # Is this an unbound method?
226
+ method_tuple(object.instance_method(name))
221
227
  end
222
- elsif object.respond_to?(:instance_method) # Is this an unbound method?
223
- method_tuple(object.instance_method(name))
224
228
  end
225
- tuple || [ name.to_s, '(?)', '' ] # Return WTF default if all the above fails.
229
+ tuple || [ name.to_s, '(?)', '?' ] # Return WTF default if all the above fails.
226
230
  end
227
231
 
228
232
  width = (tuples.size - 1).to_s.size
@@ -259,14 +263,27 @@ module AwesomePrint
259
263
  args[-1] = "*#{args[-1]}" if method.arity < 0
260
264
  end
261
265
 
262
- if method.to_s =~ /(Unbound)*Method: (.*?)[#\.]/
263
- owner = "#{$2}#{$1 ? '(unbound)' : ''}".gsub('(', ' (')
266
+ # method.to_s formats to handle:
267
+ #
268
+ # #<Method: Fixnum#zero?>
269
+ # #<Method: Fixnum(Integer)#years>
270
+ # #<Method: User(#<Module:0x00000103207c00>)#_username>
271
+ # #<Method: User(id: integer, username: string).table_name>
272
+ # #<Method: User(id: integer, username: string)(ActiveRecord::Base).current>
273
+ # #<UnboundMethod: Hello#world>
274
+ #
275
+ if method.to_s =~ /(Unbound)*Method: (.*)[#\.]/
276
+ unbound, klass = $1 && '(unbound)', $2
277
+ if klass && klass =~ /(\(\w+:\s.*?\))/ # Is this ActiveRecord-style class?
278
+ klass.sub!($1, '') # Yes, strip the fields leaving class name only.
279
+ end
280
+ owner = "#{klass}#{unbound}".gsub('(', ' (')
264
281
  end
265
282
 
266
283
  [ method.name.to_s, "(#{args.join(', ')})", owner.to_s ]
267
284
  end
268
285
 
269
- # Format hash keys as plain string regardless of underlying data type.
286
+ # Format hash keys as plain strings regardless of underlying data type.
270
287
  #------------------------------------------------------------------------------
271
288
  def plain_single_line
272
289
  plain, multiline = @options[:plain], @options[:multiline]
@@ -314,7 +331,25 @@ module AwesomePrint
314
331
  ' ' * (@indentation - @options[:indent].abs)
315
332
  end
316
333
 
317
- # To support limited output.
334
+ # To support limited output, for example:
335
+ #
336
+ # ap ('a'..'z').to_a, :limit => 3
337
+ # [
338
+ # [ 0] "a",
339
+ # [ 1] .. [24],
340
+ # [25] "z"
341
+ # ]
342
+ #
343
+ # ap (1..100).to_a, :limit => true # Default limit is 7.
344
+ # [
345
+ # [ 0] 1,
346
+ # [ 1] 2,
347
+ # [ 2] 3,
348
+ # [ 3] .. [96],
349
+ # [97] 98,
350
+ # [98] 99,
351
+ # [99] 100
352
+ # ]
318
353
  #------------------------------------------------------------------------------
319
354
  def should_be_limited?
320
355
  @options[:limit] == true or (@options[:limit].is_a?(Fixnum) and @options[:limit] > 0)
@@ -345,6 +380,5 @@ module AwesomePrint
345
380
  temp
346
381
  end
347
382
  end
348
-
349
383
  end
350
384
  end
@@ -5,6 +5,6 @@
5
5
  #------------------------------------------------------------------------------
6
6
  module AwesomePrint
7
7
  def self.version
8
- '1.0.1'
8
+ '1.0.2'
9
9
  end
10
10
  end
@@ -445,4 +445,14 @@ describe "Methods arrays" do
445
445
  hello = Hello.new
446
446
  (hello.send(:his) - hello.send(:her)).sort_by { |x| x.to_s }.should == [ :him, :his ]
447
447
  end
448
+
449
+ it "appending garbage to methods array should not raise error" do
450
+ arr = 42.methods << [ :wtf ]
451
+ arr.ai(:plain => true).should_not raise_error(TypeError)
452
+ if RUBY_VERSION < '1.9.2'
453
+ arr.ai(:plain => true).should =~ /\s+wtf\(\?\)\s+\?/ # [ :wtf ].to_s => "wtf"
454
+ else
455
+ arr.ai(:plain => true).should =~ /\s+\[:wtf\]\(\?\)\s+\?/ # [ :wtf ].to_s => [:wtf]
456
+ end
457
+ end
448
458
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: awesome_print
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.0.1
5
+ version: 1.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Michael Dvorkin
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-11-08 00:00:00 Z
13
+ date: 2011-12-20 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec