desc_method 0.1.5

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/README ADDED
@@ -0,0 +1,101 @@
1
+ A "run time RI for ruby methods", this gem allows you to query for information about objects' methods at runtime--for example within irb or ruby-debug. It reveals everything known about the method. This includes source, ri, arity, rdoc comments (1.9 only), etc.
2
+
3
+ For me it has proved quite useful, and I wouldn't do a ruby-debug session without it--you might really like it.
4
+
5
+ Examples:
6
+
7
+ >> class A;
8
+ def go(a); end;
9
+ end
10
+
11
+ >> A.desc_method :go
12
+ #<UnboundMethod: A#go> arity: 1
13
+ ri for A#go
14
+ Nothing known about A
15
+ (end ri)
16
+ def go(a)
17
+ # do nothing
18
+ end
19
+ Parameters: go(a)
20
+
21
+ >> File.desc_method :delete
22
+ ri for File.delete
23
+ ----------------------------------------------------------- File::delete
24
+ File.delete(file_name, ...) => integer
25
+ File.unlink(file_name, ...) => integer
26
+
27
+ From Ruby 1.9.1
28
+ ------------------------------------------------------------------------
29
+ Deletes the named files, returning the number of names passed as
30
+ arguments. Raises an exception on any error. See also +Dir::rmdir+.
31
+
32
+ (end ri)
33
+ #<Method: File.delete> arity: -1
34
+ appears to be a c method
35
+ #parameters signature: delete( [[:rest]] )
36
+
37
+ Or (my favorite) a debug session:
38
+
39
+ (rdb:1) l=
40
+ ...
41
+ 74 assert(assigns['order'].order_line_items.map(:unit_price).min >= -5)
42
+ ...
43
+ (rdb:1) desc_method :assert
44
+ #<Method: StoreControllerTest(Test::Unit::Assertions)#assert> arity: -2
45
+ ri for Test::Unit::Assertions#assert
46
+ ------------------------------------------ Test::Unit::Assertions#assert
47
+ assert(boolean, message=nil)
48
+
49
+ From gem test-unit-2.0.1
50
+ ------------------------------------------------------------------------
51
+ Asserts that +boolean+ is not false or nil.
52
+
53
+ Example:
54
+
55
+ assert [1, 2].include?(5)
56
+
57
+ (end ri)
58
+ def assert(boolean, message = nil)
59
+ _wrap_assertion do
60
+ assert_block("assert should not be called with a block.") do
61
+ (not block_given?)
62
+ end
63
+ assert_block(build_message(message, "<?> is not true.", boolean)) { boolean }
64
+ end
65
+ end
66
+ Parameters: assert(boolean, message = nil)
67
+
68
+ Thus, you can look at methods' source/rdocs without having to step into them. Deftly convenient.
69
+
70
+ ========= How to Install=====
71
+ $ gem install rogerdpack-desc_method
72
+ or
73
+ $ gem install rogerdpack-desc_method --source http://gems.github.com
74
+ if you don't have gems.github.com as a gem source.
75
+
76
+ Usage:
77
+ >> require 'desc_method'
78
+ >> Class.desc_method :method_name # class or instance method name
79
+ ...
80
+ >> some_instance.desc_method :method_name
81
+
82
+ Other goodies included:
83
+
84
+ Class#desc_class method
85
+
86
+ An example:
87
+ >> Object.desc_class
88
+ # outputs descriptive info about that class--RI, method list, etc.
89
+ >> Object.desc_class :verbose => true
90
+ # outputs RI, method lists including inherited methods, ancestors, all constants etc.
91
+
92
+ Kernel#methods has been monkey patched to output a "separator" between its inherited and non inherited methods--i.e.
93
+ >> instance.methods
94
+ => [:first, :second, :after_this_are_inherited>>>>>, :some_inherited_method, :another_inherited_method] # adds in that separator
95
+
96
+ I'll probably remove that in a future release since it turns out you can just run Kernel#methods(false) for about much.
97
+
98
+ === Thanks ===
99
+ This gem wraps for convenience the functionality of Method#source_location, ruby2ruby, et al, and also contains some code inspiration from manvenu, SourceRef (MBARI), and Python's Method#desc. It also wouldn't be useful without irb and the ruby-debug folks. Thanks!
100
+
101
+ Comments/suggestions welcome rogerdpack on gmail or github
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'sane'
3
+ require_rel 'method_describer'
@@ -0,0 +1,56 @@
1
+ require_rel 'method_desc'
2
+ class Class
3
+ # just runs ri against the class, outputs a big
4
+ def desc_class options = {}
5
+ # want_output = false, verbose = false
6
+ begin
7
+ puts "begin RI"
8
+ RDoc::RI::Driver.run [to_s, '--no-pager']
9
+ puts 'end ri'
10
+ rescue SystemExit
11
+ # not found
12
+ end
13
+
14
+ class_methods = methods(false)
15
+ for ancestor in ancestors[1..-1] # skip the first one, which is yourself
16
+ class_methods -= ancestor.methods(false)
17
+ end
18
+
19
+ doc = []
20
+ doc << to_s
21
+ doc += ["non inherited methods:", instance_methods(false).sort.join(", ")]
22
+ doc += ['non inherited class methods:', class_methods.sort.join(', ')]
23
+ doc += ["ancestors:", ancestors.join(', ')] if options[:verbose]
24
+ doc += ["Constants (possible sub classes):", constants.join(', ')] if constants.length > 0 && options[:verbose]
25
+ puts doc
26
+ doc if options[:want_output]
27
+ end
28
+
29
+ end
30
+
31
+ =begin
32
+ doctest:
33
+
34
+ it should return true if you run it against a "real" class
35
+ >> String.desc_class(:want_output => true).length > 1
36
+ => true
37
+ >> class A; end
38
+ >> A.desc_class(:want_output => true).length > 1
39
+ => true
40
+
41
+ it shouldn't report itself as an ancestor of itself
42
+ >> A.desc_class(:want_output => true).grep(/ancestors/).include? '[A]'
43
+ => false
44
+
45
+ also lists constants
46
+ >> A.desc_class(:want_output => true, :verbose => true).grep(/constants/i)
47
+ => [] # should be none since we didn't add any constants to A
48
+ >> class A; B = 3; end
49
+ >> A.desc_class(:want_output => true, :verbose => true).grep(/constants/i).length
50
+ => 1 # should be none since we didn't add any constants to A
51
+
52
+ should work with sub methods
53
+ >> String.desc_method(:strip)
54
+
55
+ doctest_require: '../method_desc'
56
+ =end
@@ -0,0 +1,20 @@
1
+ =begin rdoc
2
+ Supplement [monkey patch] Kernel#methods so that it returns lists that are split into two kind of [adds a marker where the inherited methods begin].
3
+ =end
4
+ module Kernel
5
+ alias :methods_old :methods
6
+ def methods all = true
7
+ if all
8
+ # give some marker designating when the inherited methods start
9
+ (public_methods(false) << :"inherited methods after this point >>") + (public_methods(true) - public_methods(false))
10
+ else
11
+ public_methods(false)
12
+ end
13
+ end
14
+ end
15
+
16
+ if $0 == __FILE__
17
+ class A; end
18
+ puts 'A.methods', A.methods(true).inspect, A.methods(false).inspect
19
+ puts 'A.new.methods', A.new.methods.inspect
20
+ end
@@ -0,0 +1,186 @@
1
+ # originally gleaned from http://p.ramaze.net/17901
2
+ require 'rubygems'
3
+ require 'rdoc'
4
+ require 'rdoc/ri/driver'
5
+ require 'sane'
6
+ begin
7
+ gem 'arguments' # TODO why is this necessary?
8
+ require 'arguments' # rogerdpack-arguments
9
+ rescue LoadError
10
+ require 'arguments' # 1.9
11
+ end
12
+ require 'ruby2ruby'
13
+
14
+ module SourceLocationDesc
15
+
16
+ # add a Method#desc which spits out all it knows about that method
17
+ # ri, location, local ri, etc.
18
+ # TODO does this work with class methods?
19
+ def desc want_just_summary = false, want_the_description_returned = false
20
+ doc = []
21
+ #_dbg
22
+ # to_s is something like "#<Method: String#strip>"
23
+ # or #<Method: GiftCertsControllerTest(Test::Unit::TestCase)#get>
24
+ # or "#<Method: A.go>"
25
+ # or "#<Method: Order(id: integer, order_number: integer).get_cc_processor>"
26
+ # or "#<Method: Order(id: integer, order_number: integer)(ActiveRecord::Base).get_cc_processor>"
27
+
28
+ string = to_s
29
+
30
+ # derive class_name
31
+ parenthese_count = string.count '('
32
+
33
+ if parenthese_count== 1
34
+ # case #<Method: GiftCertsControllerTest(Test::Unit::TestCase)#get>
35
+ # case #<Method: Order(id: integer, order_number: integer).get_cc_processor>
36
+ if string.include? "id: " # TODO huh?
37
+ string =~ /Method: (.+)\(/
38
+ else
39
+ string =~ /\(([^\(]+)\)[\.#]/ # extract out what is between last parentheses
40
+ end
41
+ class_name = $1
42
+ elsif parenthese_count == 0
43
+ # case "#<Method: A.go>"
44
+ string =~ /Method: ([^#\.]+)/
45
+ class_name = $1
46
+ elsif parenthese_count == 2
47
+ # case "#<Method: Order(id: integer, order_number: integer)(ActiveRecord::Base).get_cc_processor>"
48
+ string =~ /\(([^\(]+)\)[\.#]/
49
+ class_name = $1
50
+ else
51
+ raise 'bad ' + string
52
+ end
53
+
54
+ # now get method name, type
55
+ string =~ /Method: .*([#\.])(.*)>/ # include the # or .
56
+ joiner = $1
57
+ method_name = $2
58
+ full_name = "#{class_name}#{joiner}#{method_name}"
59
+ puts "sig: #{to_s} arity: #{arity}"
60
+ # TODO add to doc, I want it before ri for now though, and only once, so not there yet :)
61
+
62
+ # now run default RI for it
63
+ begin
64
+ puts 'searching ri for ' + full_name + "..."
65
+ RDoc::RI::Driver.run [full_name, '--no-pager'] unless want_just_summary
66
+ rescue *[StandardError, SystemExit]
67
+ # not found
68
+ end
69
+ puts '(end ri)'
70
+
71
+ # now gather up any other information we now about it, in case there are no rdocs
72
+
73
+ if !(respond_to? :source_location)
74
+ # pull out names for 1.8
75
+ begin
76
+ klass = eval(class_name)
77
+ # we don't call to_ruby to overcome ruby2ruby bug http://rubyforge.org/tracker/index.php?func=detail&aid=26891&group_id=1513&atid=5921
78
+ if joiner == '#'
79
+ doc << RubyToRuby.new.process(ParseTree.translate(klass, method_name))
80
+ else
81
+ doc << RubyToRuby.new.process(ParseTree.translate(klass.singleton_class, method_name))
82
+ end
83
+ args = Arguments.names( klass, method_name) rescue Arguments.names(klass.singleton_class, method_name)
84
+ out = []
85
+ args.each{|arg_pair|
86
+ out << arg_pair.join(' = ')
87
+ } if args
88
+ out = out.join(', ')
89
+ return out if want_just_summary
90
+
91
+ param_string = "Parameters: #{method_name}(" + out + ")"
92
+ doc << param_string unless want_the_description_returned
93
+ rescue Exception => e
94
+
95
+ puts "fail to parse tree: #{class_name} #{e} #{e.backtrace}" if $VERBOSE
96
+ end
97
+ else
98
+ # 1.9.x
99
+ file, line = source_location
100
+ if file
101
+ # then it's a pure ruby method
102
+ doc << "at #{file}:#{line}"
103
+ all_lines = File.readlines(file)
104
+ head_and_sig = all_lines[0...line]
105
+ sig = head_and_sig[-1]
106
+ head = head_and_sig[0..-2]
107
+
108
+ doc << sig
109
+ head.reverse_each do |line|
110
+ break unless line =~ /^\s*#(.*)/
111
+ doc.unshift " " + $1.strip
112
+ end
113
+
114
+ # now the real code will end with 'end' same whitespace as the first
115
+ sig_white_space = sig.scan(/\W+/)[0]
116
+ body = all_lines[line..-1]
117
+ body.each{|line|
118
+ doc << line
119
+ if line.start_with?(sig_white_space + "end")
120
+ break
121
+ end
122
+ }
123
+ # how do I get the rest now?
124
+ return sig + "\n" + head[0] if want_just_summary
125
+ else
126
+ doc << 'appears to be a c method'
127
+ end
128
+ param_string = to_s
129
+ if respond_to? :parameters
130
+ doc << "Original code signature: %s" % sig.to_s.strip if sig
131
+ doc << "#parameters signature: %s( %p )" % [name, parameters]
132
+ end
133
+ end
134
+
135
+ puts doc # always output it since RI does currently [todo make optional I suppose, and non out-putty]
136
+
137
+ if want_the_description_returned # give them something they can examine
138
+ doc
139
+ else
140
+ param_string
141
+ end
142
+ end
143
+
144
+ named_args_for :desc # just for fun, tests use it too, plus it should actually wurk without interfering...I think
145
+
146
+ end
147
+
148
+ class Method; include SourceLocationDesc; end
149
+ class UnboundMethod; include SourceLocationDesc; end
150
+
151
+ # TODO mixin from a separate module
152
+ class Object
153
+ # currently rather verbose, but will attempt to describe all it knows about a method
154
+ def desc_method name, options = {}
155
+ if self.is_a? Class
156
+ # i.e. String.strip
157
+ instance_method(name).desc(options) rescue method(name).desc(options) # rescue allows for Class.instance_method_name
158
+ else
159
+ method(name).desc(options)
160
+ end
161
+ end
162
+ end
163
+
164
+
165
+ =begin
166
+ doctest:
167
+ >> require 'pathname'
168
+ it should display the name
169
+ >> Pathname.instance_method(:children).desc(:want_the_description_returned => true).grep(/children/).size > 0
170
+ => true # ["#<UnboundMethod: Pathname#children>"]
171
+
172
+ and arity
173
+ >> Pathname.instance_method(:children).desc(:want_the_description_returned => true).grep(/arity/)
174
+ => ["#<UnboundMethod: Pathname#children> arity: -1"]
175
+
176
+ # todo: one that is guaranteed to exit you early [no docs at all ever]
177
+
178
+ wurx with class methods
179
+ >> class A; def self.go(a = 3); a=5; end; end
180
+ >> class A; def go2(a=4) a =7; end; end
181
+ >> A.desc_method(:go)
182
+ >> A.desc_method(:go2)
183
+
184
+ >> File.desc_method :delete
185
+
186
+ =end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: desc_method
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Roger Pack
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-29 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rdoc
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "2.3"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: require_all
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "1.1"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rogerdpack-arguments
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: rogerdpack-sane
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.1.2
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: ParseTree
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: ruby2ruby
67
+ type: :runtime
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ description: ruby method describer to make it possible to inspect methods [rdoc, signature, etc.] at runtime, for example while debugging.
76
+ email:
77
+ - rogerdpack@gmail.comm
78
+ executables: []
79
+
80
+ extensions: []
81
+
82
+ extra_rdoc_files: []
83
+
84
+ files:
85
+ - README
86
+ - lib/desc_method.rb
87
+ - lib/method_describer/class_desc.rb
88
+ - lib/method_describer/kernel_new_methods_list.rb
89
+ - lib/method_describer/method_desc.rb
90
+ has_rdoc: true
91
+ homepage: http://github.com/rogerdpack/method_describer
92
+ licenses: []
93
+
94
+ post_install_message:
95
+ rdoc_options: []
96
+
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: "0"
110
+ version:
111
+ requirements: []
112
+
113
+ rubyforge_project:
114
+ rubygems_version: 1.3.5
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: ruby method describer to make it possible to inspect methods [rdoc, signature, etc.] at runtime, for example while debugging.
118
+ test_files: []
119
+