rogerdpack-desc_method 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,63 @@
1
+ A "ruby method describer"--this gem allows you to introspect methods while within irb or ruby-debug. It reveals everything conceivably known about that method. This includes source, ri, arity, rdoc comments (on 1.9), etc. etc.
2
+
3
+ For me it has proved quite useful, and I wouldn't leave home without it [try it--you might really like it].
4
+
5
+ Examples:
6
+ >>
7
+ class A;
8
+ def go(a); end;
9
+ end
10
+ >> A.desc_method :go
11
+ # it outputs everything it knows about it...arity, source, RI, etc.
12
+ ri for A#go
13
+ Nothing known about A
14
+ (end ri)
15
+ #<UnboundMethod: A#go> arity: 1
16
+ A#go a
17
+ proc { |a|
18
+ # do nothing
19
+ }
20
+
21
+ an example in 1.9:
22
+ >> File.desc_method :delete
23
+ ri for File.delete
24
+ ----------------------------------------------------------- File::delete
25
+ File.delete(file_name, ...) => integer
26
+ File.unlink(file_name, ...) => integer
27
+
28
+ From Ruby 1.9.1
29
+ ------------------------------------------------------------------------
30
+ Deletes the named files, returning the number of names passed as
31
+ arguments. Raises an exception on any error. See also +Dir::rmdir+.
32
+
33
+ (end ri)
34
+ #<Method: File.delete> arity: -1
35
+ appears to be a c method
36
+ #parameters signature: delete( [[:rest]] )
37
+
38
+ ========= Installation/usage:=====
39
+ Installation:
40
+ $ gem install rogerdpack-desc_method
41
+ Usage:
42
+ >> require 'desc_method'
43
+ >> Class.desc_method :method_name # class or instance method name
44
+ ...
45
+ >> instance.desc_method :instance_method_name
46
+ ...
47
+
48
+ other goodies also included:
49
+ Class.desc_class method # outputs descriptive information about that class--ex:
50
+ >> Object.desc_class
51
+ # outputs RI, methods, etc.
52
+ or
53
+ >> Object.desc_class :verbose => true
54
+ # outputs RI, method lists including inherited methods, ancestors, constants
55
+
56
+ Kernel#method is monkey patched to output a "separator" between its inherited and non inherited methods--i.e.
57
+ >> method
58
+ => [:first, :second, :after_this_are_inherited>>>>>, :some_inherited_method, :another_inherited_method] # adds in the separator
59
+
60
+
61
+ This gem wraps (in a very convenient way) functionality provided by Method#source_location, ruby2ruby, etc. Also thanks to manvenu for some original code inspiration, SourceRef (MBARI), and ruby-debug, who made this possible. Thanks guys!
62
+
63
+ 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,170 @@
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
+
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, created_on: datetime, shipped_on: datetime, order_user_id: integer, order_status_code_id: integer, notes: text, referer: string, order_shipping_type_id: integer, product_cost: float, shipping_cost: float, tax: float, auth_transaction_id: string, promotion_id: integer, shipping_address_id: integer, billing_address_id: integer, order_account_id: integer).get_cc_processor>"
26
+
27
+ string = to_s
28
+
29
+ if string.include? ')#'
30
+ # case #<Method: GiftCertsControllerTest(Test::Unit::TestCase)#get>
31
+ string =~ /\((.*)\)/ # extract out what is between parentheses for the classname
32
+ class_name = $1
33
+ elsif string.include?( '(' ) && string.include?( ').' )
34
+ # case "Method: Order(id:...).class_method"
35
+ string =~ /Method: (.*)\(/
36
+ class_name = $1
37
+ elsif string =~ /Method: (.*)\..*>/
38
+ # case "#<Method: A.go>"
39
+ class_name = $1
40
+ else
41
+ # case "#<Method: String#strip>"
42
+ string =~ /Method: (.*)#.*/
43
+ class_name = $1
44
+ end
45
+
46
+ # now get method name, type
47
+ string =~ /Method: .*([#\.])(.*)>/ # include the # or .
48
+ joiner = $1
49
+ method_name = $2
50
+ full_name = "#{class_name}#{joiner}#{method_name}"
51
+ puts "#{to_s} arity: #{arity}" # TODO add to doc, I want it before ri for now though :)
52
+
53
+ # now run default RI for it
54
+ begin
55
+ puts 'ri for ' + full_name
56
+ RDoc::RI::Driver.run [full_name, '--no-pager'] unless want_just_summary
57
+ rescue *[StandardError, SystemExit]
58
+ # not found
59
+ end
60
+ puts '(end ri)'
61
+
62
+ # now gather up any other information we now about it, in case there are no rdocs
63
+
64
+ if !(respond_to? :source_location)
65
+ # pull out names for 1.8
66
+ begin
67
+ klass = eval(class_name)
68
+ # 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
69
+ if joiner == '#'
70
+ doc << RubyToRuby.new.process(ParseTree.translate(klass, method_name))
71
+ else
72
+ doc << RubyToRuby.new.process(ParseTree.translate(klass.singleton_class, method_name))
73
+ end
74
+ args = Arguments.names( klass, method_name) rescue Arguments.names(klass.singleton_class, method_name)
75
+ out = []
76
+ args.each{|arg_pair|
77
+ out << arg_pair.join(' = ')
78
+ }
79
+ out = out.join(', ')
80
+ return out if want_just_summary
81
+
82
+ doc << "Parameters: #{method_name}(" + out + ")"
83
+ rescue Exception => e
84
+ puts "fail to parse tree: #{class_name} #{e} #{e.backtrace}" if $VERBOSE
85
+ end
86
+ else
87
+ # 1.9.x
88
+ file, line = source_location
89
+ if file
90
+ # then it's a pure ruby method
91
+ doc << "at #{file}:#{line}"
92
+ all_lines = File.readlines(file)
93
+ head_and_sig = all_lines[0...line]
94
+ sig = head_and_sig[-1]
95
+ head = head_and_sig[0..-2]
96
+
97
+ doc << sig
98
+ head.reverse_each do |line|
99
+ break unless line =~ /^\s*#(.*)/
100
+ doc.unshift " " + $1.strip
101
+ end
102
+
103
+ # now the real code will end with 'end' same whitespace as the first
104
+ sig_white_space = sig.scan(/\W+/)[0]
105
+ body = all_lines[line..-1]
106
+ body.each{|line|
107
+ doc << line
108
+ if line.start_with?(sig_white_space + "end")
109
+ break
110
+ end
111
+ }
112
+ # how do I get the rest now?
113
+ return sig + "\n" + head[0] if want_just_summary
114
+ else
115
+ doc << 'appears to be a c method'
116
+ end
117
+ if respond_to? :parameters
118
+ doc << "Original code signature: %s" % sig.to_s.strip if sig
119
+ doc << "#parameters signature: %s( %p )" % [name, parameters]
120
+ end
121
+ end
122
+
123
+ puts doc # always output it since RI does currently [todo make optional I suppose, and non out-putty]
124
+
125
+ doc if want_the_description_returned # give them something they can examine
126
+ end
127
+
128
+ named_args_for :desc # just for fun, tests use it too, plus it should actually wurk without interfering...I think
129
+
130
+ end
131
+
132
+ class Method; include SourceLocationDesc; end
133
+ class UnboundMethod; include SourceLocationDesc; end
134
+
135
+ # TODO mixin from a separate module
136
+ class Object
137
+ # currently rather verbose, but will attempt to describe all it knows about a method
138
+ def desc_method name, options = {}
139
+ if self.is_a? Class
140
+ # i.e. String.strip
141
+ instance_method(name).desc(options) rescue method(name).desc(options) # rescue allows for Class.instance_method_name
142
+ else
143
+ method(name).desc(options)
144
+ end
145
+ end
146
+ end
147
+
148
+
149
+ =begin
150
+ doctest:
151
+ >> require 'pathname'
152
+ it should display the name
153
+ >> Pathname.instance_method(:children).desc(:want_the_description_returned => true).grep(/children/).size > 0
154
+ => true # ["#<UnboundMethod: Pathname#children>"]
155
+
156
+ and arity
157
+ >> Pathname.instance_method(:children).desc(:want_the_description_returned => true).grep(/arity/)
158
+ => ["#<UnboundMethod: Pathname#children> arity: -1"]
159
+
160
+ # todo: one that is guaranteed to exit you early [no docs at all ever]
161
+
162
+ wurx with class methods
163
+ >> class A; def self.go(a = 3); a=5; end; end
164
+ >> class A; def go2(a=4) a =7; end; end
165
+ >> A.desc_method(:go)
166
+ >> A.desc_method(:go2)
167
+
168
+ >> File.desc_method :delete
169
+
170
+ =end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rogerdpack-desc_method
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Roger Pack
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-16 00:00:00 -07: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: false
91
+ homepage: http://github.com/rogerdpack/method_describer
92
+ licenses:
93
+ post_install_message:
94
+ rdoc_options: []
95
+
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: "0"
103
+ version:
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: "0"
109
+ version:
110
+ requirements: []
111
+
112
+ rubyforge_project:
113
+ rubygems_version: 1.3.5
114
+ signing_key:
115
+ specification_version: 2
116
+ summary: ruby method describer to make it possible to inspect methods [rdoc, signature, etc.] at runtime, for example while debugging.
117
+ test_files: []
118
+