Module: Boson::ArgumentInspector
- Extended by:
- ArgumentInspector
- Included in:
- ArgumentInspector
- Defined in:
- lib/boson/inspectors/argument_inspector.rb
Overview
Extracts arguments and their default values from methods either by by scraping a method’s text or with method_added and brute force eval (thanks to eigenclass).
Constant Summary collapse
- MAX_ARGS =
Max number of arguments extracted per method with scrape_with_eval
10
Instance Method Summary collapse
-
#format_arguments(params, values, arity, num_args) ⇒ Object
process params + values to return array of argument arrays.
-
#print_debug_message(klass, meth) ⇒ Object
:nodoc:.
-
#scrape_with_eval(meth, klass, object) ⇒ Object
Scrapes non-private methods for argument names and default values.
-
#scrape_with_text(file_string, meth) ⇒ Object
Returns same argument arrays as scrape_with_eval but argument defaults haven’t been evaluated.
-
#trace_method_args(meth, klass, object) ⇒ Object
:nodoc:.
Instance Method Details
#format_arguments(params, values, arity, num_args) ⇒ Object
process params + values to return array of argument arrays
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/boson/inspectors/argument_inspector.rb', line 39 def format_arguments(params, values, arity, num_args) #:nodoc: params ||= [] params = params[0,num_args] params.inject([[], 0]) do |(a, i), x| if Array === values[i] [a << ["*#{x}"], i+1] else if arity < 0 && i >= arity.abs - 1 [a << [x.to_s, values[i]], i + 1] else [a << [x.to_s], i+1] end end end.first end |
#print_debug_message(klass, meth) ⇒ Object
:nodoc:
34 35 36 |
# File 'lib/boson/inspectors/argument_inspector.rb', line 34 def (klass, meth) #:nodoc: warn "DEBUG: Error while scraping arguments from #{klass.to_s[/\w+$/]}##{meth}: #{$!.}" end |
#scrape_with_eval(meth, klass, object) ⇒ Object
Scrapes non-private methods for argument names and default values. Returns arguments as array of argument arrays with optional default value as a second element.
Examples:
def meth1(arg1, arg2='val', options={}) -> [['arg1'], ['arg2', 'val'], ['options', {}]]
def meth2(*args) -> [['*args']]
21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/boson/inspectors/argument_inspector.rb', line 21 def scrape_with_eval(meth, klass, object) unless %w[initialize].include?(meth.to_s) return if class << object; private_instance_methods(true).map {|e| e.to_s } end.include?(meth.to_s) end params, values, arity, num_args = trace_method_args(meth, klass, object) return if local_variables == params # nothing new found format_arguments(params, values, arity, num_args) rescue Exception (klass, meth) if Boson::Runner.debug ensure set_trace_func(nil) end |
#scrape_with_text(file_string, meth) ⇒ Object
Returns same argument arrays as scrape_with_eval but argument defaults haven’t been evaluated.
7 8 9 10 11 12 |
# File 'lib/boson/inspectors/argument_inspector.rb', line 7 def scrape_with_text(file_string, meth) tabspace = "[ \t]" if match = /^#{tabspace}*def#{tabspace}+(?:\w+\.)?#{Regexp.quote(meth)}#{tabspace}*($|(?:\(|\s+)([^\n\)]+)\s*\)?\s*$)/.match(file_string) (match.to_a[2] || '').strip.split(/\s*,\s*/).map {|e| e.split(/\s*=\s*/)} end end |
#trace_method_args(meth, klass, object) ⇒ Object
:nodoc:
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/boson/inspectors/argument_inspector.rb', line 55 def trace_method_args(meth, klass, object) #:nodoc: file = line = params = values = nil arity = klass.instance_method(meth).arity set_trace_func lambda{|event, file, line, id, binding, classname| begin if event[/call/] && classname == klass && id == meth params = eval("local_variables", binding) values = eval("local_variables.map{|x| eval(x.to_s)}", binding) throw :done end rescue Exception (klass, meth) if Boson::Runner.debug end } if arity >= 0 num_args = arity catch(:done){ object.send(meth, *(0...arity)) } else num_args = 0 # determine number of args (including splat & block) MAX_ARGS.downto(arity.abs - 1) do |i| catch(:done) do begin object.send(meth, *(0...i)) rescue Exception end end # all nils if there's no splat and we gave too many args next if !values || values.compact.empty? k = nil values.each_with_index{|x,j| break (k = j) if Array === x} num_args = k ? k+1 : i break end args = (0...arity.abs-1).to_a catch(:done) do args.empty? ? object.send(meth) : object.send(meth, *args) end end set_trace_func(nil) return [params, values, arity, num_args] end |