awesome_print 0.2.1 → 0.4.0

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,31 @@
1
+ 0.4.0
2
+ - 'ap object' now returns the object (Stephan Hagemann)
3
+ - Added :html => true option to enable HTML colors rather that ANSI (ex. Sinatra templates)
4
+ - Added AwesomePrint.force_colors! to allow color output on demand (Andrew O'Brien)
5
+ - Added MongoMapper formatter mixin (Elpizo Choi)
6
+ - Fixed formatting of methods array when object#method is overridden
7
+ - Fixed potential stack errors by checking whether AwesomePrint is already loaded
8
+ - Improved Ruby 1.8.6 and 1.8.7 compatibility
9
+ - Improved Windows compatibility (Viktar Basharymau)
10
+
11
+ 0.3.2
12
+ - Make sure Rails mixins get loaded in Rails console when required from .irbrc
13
+ - Fixed an issue with classes that define their own #send method (ex: Socket)
14
+ - Fixed compatibility issue with Liquid gem that defines Module#liquid_methods
15
+ - Fixed hash spec for Ruby < 1.9 where order of hash keys is not guaranteed
16
+ - Added :sorted_hash_keys option to sort hash keys (Ed Ruder)
17
+
18
+ 0.3.1 RubyConf X edition
19
+ - Fixed Ruby 1.8.6 compatibility issues (thanks, Tim!)
20
+ - Fixed stack overflow issue with Rails 2.3.x console
21
+
22
+ 0.3.0
23
+ - Display object.methods and family in human readable format
24
+ - Objects inherited from Array, Hash, File, Dir, and Struct are shown as their base class
25
+ - Added option to suppress array index in output (Sean Gallagher)
26
+ - Updated README on how to set up ~/.irbrc for MacRuby (Eloy Duran)
27
+ - Specs pass 100% with Ruby 1.8.7/RSpec 1.3 and Ruby 1.9.2/RSpec 2.0
28
+
1
29
  0.2.1
2
30
  - ap can now be used within Rails templates (ex. <%= ap object %>)
3
31
  - Added support for printing Struct
data/LICENSE CHANGED
@@ -1,4 +1,5 @@
1
- Copyright (c) 2010 Michael Dvorkin
1
+ Copyright (c) 2010-2011 Michael Dvorkin
2
+ twitter.com/mid
2
3
  %w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
3
4
 
4
5
  Permission is hereby granted, free of charge, to any person obtaining
data/README.md CHANGED
@@ -8,21 +8,24 @@ objects and usage within Rails templates are supported via included mixins.
8
8
  $ gem install awesome_print
9
9
 
10
10
  # Installing as Rails plugin
11
- $ ruby script/plugin install http://github.com/michaeldv/awesome_print_.git
11
+ $ ruby script/plugin install http://github.com/michaeldv/awesome_print.git
12
12
 
13
13
  # Cloning the repository
14
- $ git clone git://github.com/michaeldv/awesome_print_.git
14
+ $ git clone git://github.com/michaeldv/awesome_print.git
15
15
 
16
16
  ### Usage ###
17
17
 
18
- require "ap"
18
+ require "awesome_print"
19
19
  ap object, options = {}
20
20
 
21
21
  Default options:
22
22
 
23
- :multiline => true,
24
- :plain => false,
25
- :indent => 4,
23
+ :multiline => true, # Display in multiple lines.
24
+ :plain => false, # Use colors.
25
+ :indent => 4, # Indent using 4 spaces.
26
+ :index => true, # Display array indices.
27
+ :html => false, # Use ANSI color codes rather than HTML.
28
+ :sorted_hash_keys => false, # Do not sort hash keys.
26
29
  :color => {
27
30
  :array => :white,
28
31
  :bignum => :blue,
@@ -46,7 +49,7 @@ Supported color names:
46
49
 
47
50
  ### Examples ###
48
51
  $ cat > 1.rb
49
- require "ap"
52
+ require "awesome_print"
50
53
  data = [ false, 42, %w(forty two), { :now => Time.now, :class => Time.now.class, :distance => 42e42 } ]
51
54
  ap data
52
55
  ^D
@@ -66,7 +69,7 @@ Supported color names:
66
69
  ]
67
70
 
68
71
  $ cat > 2.rb
69
- require "ap"
72
+ require "awesome_print"
70
73
  data = { :now => Time.now, :class => Time.now.class, :distance => 42e42 }
71
74
  ap data, :indent => -2 # <-- Left align hash keys.
72
75
  ^D
@@ -78,7 +81,7 @@ Supported color names:
78
81
  }
79
82
 
80
83
  $ cat > 3.rb
81
- require "ap"
84
+ require "awesome_print"
82
85
  data = [ false, 42, %w(forty two) ]
83
86
  data << data # <-- Nested array.
84
87
  ap data, :multiline => false
@@ -86,10 +89,58 @@ Supported color names:
86
89
  $ ruby 3.rb
87
90
  [ false, 42, [ "forty", "two" ], [...] ]
88
91
 
92
+ $ cat > 4.rb
93
+ require "awesome_print"
94
+ class Hello
95
+ def self.world(x, y, z = nil, &blk)
96
+ end
97
+ end
98
+ ap Hello.methods - Class.methods
99
+ ^D
100
+ $ ruby 4.rb
101
+ [
102
+ [0] world(x, y, *z, &blk) Hello
103
+ ]
104
+
105
+ $ cat > 5.rb
106
+ require "awesome_print"
107
+ ap (''.methods - Object.methods).grep(/!/)
108
+ ^D
109
+ $ ruby 5.rb
110
+ [
111
+ [ 0] capitalize!() String
112
+ [ 1] chomp!(*arg1) String
113
+ [ 2] chop!() String
114
+ [ 3] delete!(*arg1) String
115
+ [ 4] downcase!() String
116
+ [ 5] encode!(*arg1) String
117
+ [ 6] gsub!(*arg1) String
118
+ [ 7] lstrip!() String
119
+ [ 8] next!() String
120
+ [ 9] reverse!() String
121
+ [10] rstrip!() String
122
+ [11] slice!(*arg1) String
123
+ [12] squeeze!(*arg1) String
124
+ [13] strip!() String
125
+ [14] sub!(*arg1) String
126
+ [15] succ!() String
127
+ [16] swapcase!() String
128
+ [17] tr!(arg1, arg2) String
129
+ [18] tr_s!(arg1, arg2) String
130
+ [19] upcase!() String
131
+ ]
132
+
133
+ $ cat > 6.rb
134
+ require "awesome_print"
135
+ ap 42 == ap(42)
136
+ ^D
137
+ $ ruby 6.rb
138
+ 42
139
+ true
140
+
89
141
  ### Example (Rails console) ###
90
- $ ruby script/console
91
- Loading development environment (Rails 2.3.5)
92
- rails> require "ap"
142
+ $ rails console
143
+ rails> require "awesome_print"
93
144
  rails> ap Account.all(:limit => 2)
94
145
  [
95
146
  [0] #<Account:0x1033220b8> {
@@ -149,33 +200,47 @@ To use awesome_print as default formatter in irb and Rails console add the follo
149
200
  lines into your ~/.irbrc file:
150
201
 
151
202
  require "rubygems"
152
- require "ap"
153
- IRB::Irb.class_eval do
154
- def output_value
155
- ap @context.last_value
203
+ require "awesome_print"
204
+
205
+ unless IRB.version.include?('DietRB')
206
+ IRB::Irb.class_eval do
207
+ def output_value
208
+ ap @context.last_value
209
+ end
156
210
  end
211
+ else # MacRuby
212
+ IRB.formatter = Class.new(IRB::Formatter) do
213
+ def inspect_object(object)
214
+ object.ai
215
+ end
216
+ end.new
157
217
  end
158
218
 
159
219
  ### Logger Convenience Method ###
160
- awesome_print adds an ap method to the Logger and ActiveSupport::BufferedLogger classes,
161
- allowing you to call:
220
+ awesome_print adds the 'ap' method to the Logger and ActiveSupport::BufferedLogger classes
221
+ letting you call:
162
222
 
163
223
  logger.ap object
164
224
 
165
- By default, this logs at the :debug level. You can override that globally with
225
+ By default, this logs at the :debug level. You can override that globally with:
166
226
 
167
227
  :log_level => :info
168
228
 
169
- in the custom defaults (see below), or you can override on a per call basis with
229
+ in the custom defaults (see below). You can also override on a per call basis with:
170
230
 
171
231
  logger.ap object, :warn
172
232
 
173
233
  ### ActionView Convenience Method ###
174
- awesome_print adds an ap method to the ActionView::Base class making it available
234
+ awesome_print adds the 'ap' method to the ActionView::Base class making it available
175
235
  within Rails templates. For example:
176
236
 
177
237
  <%= ap @accounts.first %>
178
238
 
239
+ With other web frameworks (ex: in Sinatra templates) you can explicitly request HTML
240
+ formatting:
241
+
242
+ <%= ap @accounts.first, :html => true %>
243
+
179
244
  ### Setting Custom Defaults ###
180
245
  You can set your own default options by creating ``.aprc`` file in your home
181
246
  directory. Within that file assign your defaults to ``AwesomePrint.defaults``.
@@ -190,6 +255,12 @@ For example:
190
255
  }
191
256
  }
192
257
 
258
+ ### Running Specs ###
259
+
260
+ $ gem install rspec # RSpec 2.x is the requirement.
261
+ $ rake spec # Run the entire spec suite.
262
+ $ rspec spec/logger_spec.rb # Run individual spec file.
263
+
193
264
  ### Note on Patches/Pull Requests ###
194
265
  * Fork the project on Github.
195
266
  * Make your feature addition or bug fix.
@@ -199,12 +270,22 @@ For example:
199
270
 
200
271
  ### Contributors ###
201
272
 
273
+ * Andrew O'Brien -- https://github.com/AndrewO
202
274
  * Daniel Bretoi -- http://github.com/danielb2
203
- * eregon -- http://github.com/eregon
275
+ * Eloy Duran -- http://github.com/alloy
276
+ * Elpizo Choi -- https://github.com/fuJiin
277
+ * Benoit Daloze -- http://github.com/eregon
278
+ * Sean Gallagher -- http://github.com/torandu
279
+ * Stephan Hagemann -- https://github.com/shageman
280
+ * Tim Harper -- http://github.com/timcharper
204
281
  * Tobias Crawley -- http://github.com/tobias
282
+ * Viktar Basharymau -- https://github.com/DNNX
205
283
 
206
284
  ### License ###
207
- Copyright (c) 2010 Michael Dvorkin
285
+ Copyright (c) 2010-2011 Michael Dvorkin
286
+
287
+ twitter.com/mid
288
+
208
289
  %w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
209
290
 
210
- Released under the MIT license. See LICENSE file for details.
291
+ Released under the MIT license. See LICENSE file for details.
data/Rakefile CHANGED
@@ -11,9 +11,8 @@ begin
11
11
  gem.email = "mike@dvorkin.net"
12
12
  gem.homepage = "http://github.com/michaeldv/awesome_print"
13
13
  gem.authors = ["Michael Dvorkin"]
14
- gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_development_dependency "rspec", ">= 2.5.0"
15
15
  gem.files = FileList["[A-Z]*", "lib/**/*.rb", "rails/*.rb", "spec/*", "init.rb"]
16
- gem.has_rdoc = false
17
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
17
  end
19
18
  Jeweler::GemcutterTasks.new
@@ -21,16 +20,15 @@ rescue LoadError
21
20
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
21
  end
23
22
 
24
- require 'spec/rake/spectask'
25
- Spec::Rake::SpecTask.new(:spec) do |spec|
26
- spec.libs << 'lib' << 'spec'
27
- spec.spec_files = FileList['spec/**/*_spec.rb']
23
+ require "rspec/core/rake_task"
24
+ RSpec::Core::RakeTask.new(:spec) do |spec|
25
+ spec.pattern = 'spec/**/*_spec.rb'
26
+ spec.rspec_opts = ['--color']
28
27
  end
29
28
 
30
- Spec::Rake::SpecTask.new(:rcov) do |spec|
31
- spec.libs << 'lib' << 'spec'
32
- spec.pattern = 'spec/**/*_spec.rb'
29
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
33
30
  spec.rcov = true
31
+ spec.rcov_opts = %q[--exclude "spec"]
34
32
  end
35
33
 
36
34
  task :spec => :check_dependencies
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.4.0
data/init.rb CHANGED
@@ -1 +1 @@
1
- require File.join(File.dirname(__FILE__), "lib", "ap")
1
+ require File.join(File.dirname(__FILE__), "lib", "awesome_print")
@@ -1,19 +1,24 @@
1
- # Copyright (c) 2010 Michael Dvorkin
1
+ # Copyright (c) 2010-2011 Michael Dvorkin
2
2
  #
3
3
  # Awesome Print is freely distributable under the terms of MIT license.
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
5
  #------------------------------------------------------------------------------
6
+ require "cgi"
6
7
  require "shellwords"
7
8
 
8
9
  class AwesomePrint
9
- AP = :__awesome_print__
10
- CORE = [ :array, :hash, :class, :file, :dir, :bigdecimal, :rational, :struct ]
10
+ AP = :__awesome_print__ unless defined?(AwesomePrint::AP)
11
+ CORE = [ :array, :hash, :class, :file, :dir, :bigdecimal, :rational, :struct, :method, :unboundmethod ] unless defined?(AwesomePrint::CORE)
12
+ @@force_colors = false
11
13
 
12
14
  def initialize(options = {})
13
15
  @options = {
14
- :multiline => true,
15
- :plain => false,
16
- :indent => 4,
16
+ :multiline => true, # Display in multiple lines.
17
+ :plain => false, # Use colors.
18
+ :indent => 4, # Indent using 4 spaces.
19
+ :index => true, # Display array indices.
20
+ :html => false, # Use ANSI color codes rather than HTML.
21
+ :sorted_hash_keys => false, # Do not sort hash keys.
17
22
  :color => {
18
23
  :array => :white,
19
24
  :bigdecimal => :blue,
@@ -28,7 +33,9 @@ class AwesomePrint
28
33
  :string => :yellowish,
29
34
  :symbol => :cyanish,
30
35
  :time => :greenish,
31
- :trueclass => :green
36
+ :trueclass => :green,
37
+ :method => :purpleish,
38
+ :args => :pale
32
39
  }
33
40
  }
34
41
 
@@ -39,7 +46,8 @@ class AwesomePrint
39
46
  @indentation = @options[:indent].abs
40
47
  Thread.current[AP] ||= []
41
48
  end
42
-
49
+
50
+
43
51
  private
44
52
 
45
53
  # Format an array.
@@ -47,18 +55,23 @@ class AwesomePrint
47
55
  def awesome_array(a)
48
56
  return "[]" if a == []
49
57
 
50
- if @options[:multiline]
58
+ if a.instance_variable_defined?('@__awesome_methods__')
59
+ methods_array(a)
60
+ elsif @options[:multiline]
51
61
  width = (a.size - 1).to_s.size
52
62
  data = a.inject([]) do |arr, item|
53
- index = colorize("#{indent}[#{arr.size.to_s.rjust(width)}] ", :array)
63
+ index = if @options[:index]
64
+ colorize("#{indent}[#{arr.size.to_s.rjust(width)}] ", :array)
65
+ else
66
+ colorize(indent, :array)
67
+ end
54
68
  indented do
55
69
  arr << (index << awesome(item))
56
70
  end
57
71
  end
58
72
  "[\n" << data.join(",\n") << "\n#{outdent}]"
59
73
  else
60
- data = a.inject([]) { |arr, item| arr << awesome(item) }
61
- "[ #{data.join(', ')} ]"
74
+ "[ " << a.map{ |item| awesome(item) }.join(", ") << " ]"
62
75
  end
63
76
  end
64
77
 
@@ -67,23 +80,24 @@ class AwesomePrint
67
80
  def awesome_hash(h)
68
81
  return "{}" if h == {}
69
82
 
70
- data = h.keys.inject([]) do |arr, key|
83
+ keys = @options[:sorted_hash_keys] ? h.keys.sort { |a, b| a.to_s <=> b.to_s } : h.keys
84
+ data = keys.map do |key|
71
85
  plain_single_line do
72
- arr << [ awesome(key), h[key] ]
86
+ [ awesome(key), h[key] ]
73
87
  end
74
88
  end
75
89
 
76
90
  width = data.map { |key, | key.size }.max || 0
77
91
  width += @indentation if @options[:indent] > 0
78
92
 
79
- data = data.inject([]) do |arr, (key, value)|
93
+ data = data.map do |key, value|
80
94
  if @options[:multiline]
81
95
  formatted_key = (@options[:indent] >= 0 ? key.rjust(width) : indent + key.ljust(width))
82
96
  else
83
97
  formatted_key = key
84
98
  end
85
99
  indented do
86
- arr << (formatted_key << colorize(" => ", :hash) << awesome(value))
100
+ formatted_key << colorize(" => ", :hash) << awesome(value)
87
101
  end
88
102
  end
89
103
  if @options[:multiline]
@@ -93,7 +107,7 @@ class AwesomePrint
93
107
  end
94
108
  end
95
109
 
96
- # Format a Struct. If @options[:indent] if negative left align hash keys.
110
+ # Format a Struct. If @options[:indent] is negative left align hash keys.
97
111
  #------------------------------------------------------------------------------
98
112
  def awesome_struct(s)
99
113
  h = {}
@@ -132,10 +146,18 @@ class AwesomePrint
132
146
  end
133
147
  alias :awesome_rational :awesome_bigdecimal
134
148
 
149
+ # Format a method.
150
+ #------------------------------------------------------------------------------
151
+ def awesome_method(m)
152
+ name, args, owner = method_tuple(m)
153
+ "#{colorize(owner, :class)}##{colorize(name, :method)}#{colorize(args, :args)}"
154
+ end
155
+ alias :awesome_unboundmethod :awesome_method
156
+
135
157
  # Catch all method to format an arbitrary object.
136
158
  #------------------------------------------------------------------------------
137
159
  def awesome_self(object, appear = {})
138
- colorize(object.inspect << appear[:with].to_s, appear[:as] || declassify(object))
160
+ colorize(object.inspect.to_s << appear[:with].to_s, appear[:as] || declassify(object))
139
161
  end
140
162
 
141
163
  # Dispatcher that detects data nesting and invokes object-aware formatter.
@@ -153,6 +175,40 @@ class AwesomePrint
153
175
  end
154
176
  end
155
177
 
178
+ # Format object.methods array.
179
+ #------------------------------------------------------------------------------
180
+ def methods_array(a)
181
+ object = a.instance_variable_get('@__awesome_methods__')
182
+ tuples = a.map do |name|
183
+ tuple = if object.respond_to?(name, true) # Is this a regular method?
184
+ the_method = object.method(name) rescue nil # Avoid potential ArgumentError if object#method is overridden.
185
+ if the_method && the_method.respond_to?(:arity) # Is this original object#method?
186
+ method_tuple(the_method) # Yes, we are good.
187
+ end
188
+ elsif object.respond_to?(:instance_method) # Is this an unbound method?
189
+ method_tuple(object.instance_method(name))
190
+ end
191
+ tuple || [ name.to_s, '(?)', '' ] # Return WTF default if all the above fails.
192
+ end
193
+
194
+ width = (tuples.size - 1).to_s.size
195
+ name_width = tuples.map { |item| item[0].size }.max || 0
196
+ args_width = tuples.map { |item| item[1].size }.max || 0
197
+
198
+ data = tuples.inject([]) do |arr, item|
199
+ index = if @options[:index]
200
+ "#{indent}[#{arr.size.to_s.rjust(width)}]"
201
+ else
202
+ indent
203
+ end
204
+ indented do
205
+ arr << "#{index} #{colorize(item[0].rjust(name_width), :method)}#{colorize(item[1].ljust(args_width), :args)} #{colorize(item[2], :class)}"
206
+ end
207
+ end
208
+
209
+ "[\n" << data.join("\n") << "\n#{outdent}]"
210
+ end
211
+
156
212
  # Format nested data, for example:
157
213
  # arr = [1, 2]; arr << arr
158
214
  # => [1,2, [...]]
@@ -174,26 +230,57 @@ class AwesomePrint
174
230
  CORE.grep(declassify(object))[0] || :self
175
231
  end
176
232
 
177
- # Turn class name into symbol, ex: Hello::World => :hello_world.
233
+ # Turn class name into symbol, ex: Hello::World => :hello_world. Classes that
234
+ # inherit from Array, Hash, File, Dir, and Struct are treated as the base class.
178
235
  #------------------------------------------------------------------------------
179
236
  def declassify(object)
180
- if object.is_a?(Struct)
181
- :struct
182
- else
183
- object.class.to_s.gsub(/:+/, "_").downcase.to_sym
237
+ case object
238
+ when Array then :array
239
+ when Hash then :hash
240
+ when File then :file
241
+ when Dir then :dir
242
+ when Struct then :struct
243
+ else object.class.to_s.gsub(/:+/, "_").downcase.to_sym
184
244
  end
185
245
  end
186
246
 
187
247
  # Pick the color and apply it to the given string as necessary.
188
248
  #------------------------------------------------------------------------------
189
249
  def colorize(s, type)
190
- if @options[:plain] || @options[:color][type].nil?
191
- s
250
+ s = CGI.escapeHTML(s) if @options[:html]
251
+ if @options[:plain] || !@options[:color][type] || !colorize?
252
+ @options[:html] ? "<pre>#{s}</pre>" : s
192
253
  else
193
- s.send(@options[:color][type])
254
+ s.send(@options[:color][type], @options[:html])
194
255
  end
195
256
  end
196
257
 
258
+ # Return [ name, arguments, owner ] tuple for a given method.
259
+ #------------------------------------------------------------------------------
260
+ def method_tuple(method)
261
+ if method.respond_to?(:parameters) # Ruby 1.9.2+
262
+ # See http://ruby.runpaint.org/methods#method-objects-parameters
263
+ args = method.parameters.inject([]) do |arr, (type, name)|
264
+ name ||= (type == :block ? 'block' : "arg#{arr.size + 1}")
265
+ arr << case type
266
+ when :req then name.to_s
267
+ when :opt, :rest then "*#{name}"
268
+ when :block then "&#{name}"
269
+ else '?'
270
+ end
271
+ end
272
+ else # See http://ruby-doc.org/core/classes/Method.html#M001902
273
+ args = (1..method.arity.abs).map { |i| "arg#{i}" }
274
+ args[-1] = "*#{args[-1]}" if method.arity < 0
275
+ end
276
+
277
+ if method.to_s =~ /(Unbound)*Method: (.*?)[#\.]/
278
+ owner = "#{$2}#{$1 ? '(unbound)' : ''}".gsub('(', ' (')
279
+ end
280
+
281
+ [ method.name.to_s, "(#{args.join(', ')})", owner.to_s ]
282
+ end
283
+
197
284
  # Format hash keys as plain string regardless of underlying data type.
198
285
  #------------------------------------------------------------------------------
199
286
  def plain_single_line
@@ -239,6 +326,19 @@ class AwesomePrint
239
326
  $stderr.puts "Could not load #{dotfile}: #{e}"
240
327
  end
241
328
 
329
+ # Return true if we are to colorize the output.
330
+ #------------------------------------------------------------------------------
331
+ def colorize?
332
+ @@force_colors || (STDOUT.tty? && ((ENV['TERM'] && ENV['TERM'] != 'dumb') || ENV['ANSICON']))
333
+ end
334
+
335
+ # Class accessor to force colorized output (ex. forked subprocess where TERM
336
+ # might be dumb).
337
+ #------------------------------------------------------------------------------
338
+ def self.force_colors!(value = true)
339
+ @@force_colors = value
340
+ end
341
+
242
342
  # Class accessors for custom defaults.
243
343
  #------------------------------------------------------------------------------
244
344
  def self.defaults
@@ -0,0 +1,71 @@
1
+ # Copyright (c) 2010-2011 Michael Dvorkin
2
+ #
3
+ # Awesome Print is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ #
7
+ # The following makes it possible to invoke awesome_print while performing
8
+ # operations on method arrays, ex:
9
+ #
10
+ # ap [].methods - Object.methods
11
+ # ap ''.methods.grep(/!|\?/)
12
+ #
13
+ # If you could think of a better way please let me know :-)
14
+ #
15
+ class Array #:nodoc:
16
+ [ :-, :& ].each do |operator|
17
+ original_operator = instance_method(operator)
18
+
19
+ define_method operator do |*args|
20
+ arr = original_operator.bind(self).call(*args)
21
+ if self.instance_variable_defined?('@__awesome_methods__')
22
+ arr.instance_variable_set('@__awesome_methods__', self.instance_variable_get('@__awesome_methods__'))
23
+ arr.sort! { |a, b| a.to_s <=> b.to_s } # Need the block since Ruby 1.8.x can't sort arrays of symbols.
24
+ end
25
+ arr
26
+ end
27
+ end
28
+ #
29
+ # Intercepting Array#grep needs a special treatment since grep accepts
30
+ # an optional block.
31
+ #
32
+ alias :original_grep :grep
33
+ def grep(pattern, &blk)
34
+ #
35
+ # The following looks rather insane and I've sent numerous hours trying
36
+ # to figure it out. The problem is that if grep gets called with the
37
+ # block, for example:
38
+ #
39
+ # [].methods.grep(/(.+?)_by/) { $1.to_sym }
40
+ #
41
+ # ...then simple:
42
+ #
43
+ # original_grep(pattern, &blk)
44
+ #
45
+ # doesn't set $1 within the grep block which causes nil.to_sym failure.
46
+ # The workaround below has been tested with Ruby 1.8.7/Rails 2.3.8 and
47
+ # Ruby 1.9.2/Rails 3.0.0. For more info see the following thread dating
48
+ # back to 2003 when Ruby 1.8.0 was as fresh off the grill as Ruby 1.9.2
49
+ # is in 2010 :-)
50
+ #
51
+ # http://www.justskins.com/forums/bug-when-rerouting-string-52852.html
52
+ #
53
+ # BTW, if you figure out a better way of intercepting Array#grep please
54
+ # let me know: twitter.com/mid -- or just say hi so I know you've read
55
+ # the comment :-)
56
+ #
57
+ arr = unless blk
58
+ original_grep(pattern)
59
+ else
60
+ original_grep(pattern) do |match|
61
+ eval("%Q/#{match.to_s.gsub('/', '\/')}/ =~ #{pattern.inspect}", blk.binding)
62
+ yield match
63
+ end
64
+ end
65
+ if self.instance_variable_defined?('@__awesome_methods__')
66
+ arr.instance_variable_set('@__awesome_methods__', self.instance_variable_get('@__awesome_methods__'))
67
+ arr.reject! { |item| !(item.is_a?(Symbol) || item.is_a?(String)) } # grep block might return crap.
68
+ end
69
+ arr
70
+ end
71
+ end
@@ -0,0 +1,17 @@
1
+ # Copyright (c) 2010-2011 Michael Dvorkin
2
+ #
3
+ # Awesome Print is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ class Class #:nodoc:
7
+ # Remaining public/private etc. '_methods' are handled in core_ext/object.rb.
8
+ %w(instance_methods private_instance_methods protected_instance_methods public_instance_methods).each do |name|
9
+ original_method = instance_method(name)
10
+
11
+ define_method name do |*args|
12
+ methods = original_method.bind(self).call(*args)
13
+ methods.instance_variable_set('@__awesome_methods__', self) # Evil?!
14
+ methods.sort!
15
+ end
16
+ end
17
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010 Michael Dvorkin
1
+ # Copyright (c) 2010-2011 Michael Dvorkin
2
2
  #
3
3
  # Awesome Print is freely distributable under the terms of MIT license.
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
@@ -13,6 +13,7 @@ module Kernel
13
13
 
14
14
  def ap(object, options = {})
15
15
  puts object.ai(options)
16
+ object
16
17
  end
17
18
  alias :awesome_print :ap
18
19
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010 Michael Dvorkin
1
+ # Copyright (c) 2010-2011 Michael Dvorkin
2
2
  #
3
3
  # Awesome Print is freely distributable under the terms of MIT license.
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
@@ -14,5 +14,5 @@ module AwesomePrintLogger
14
14
 
15
15
  end
16
16
 
17
- Logger.send(:include, AwesomePrintLogger) if defined?(Logger)
17
+ Logger.send(:include, AwesomePrintLogger)
18
18
  ActiveSupport::BufferedLogger.send(:include, AwesomePrintLogger) if defined?(::ActiveSupport::BufferedLogger)