rogerdpack-desc_method 0.1.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/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
+