Class: Fire
- Inherits:
-
Object
show all
- Defined in:
- lib/ruby-fire.rb,
lib/ruby-fire/version.rb
Defined Under Namespace
Classes: TracePointTerminate
Constant Summary
collapse
- METHODS_CODE =
'public_methods(false)+private_methods(false)'
- TOPLEVEL_METHODS =
TOPLEVEL_BINDING.eval(METHODS_CODE)
- VERSION =
'0.2.2'
Class Method Summary
collapse
-
.fire(*args, **kwargs, &block) ⇒ Object
-
.method_arguments(func_parameters, params) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity.
-
.new_method?(func) ⇒ Boolean
-
.parameters_call(func, func_parameters, params, error = true) ⇒ Object
-
.trace_parameters(trace_func) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity.
Instance Method Summary
collapse
Constructor Details
#initialize(rec = nil, program_name: nil, &block) ⇒ Fire
Returns a new instance of Fire.
109
110
111
112
113
114
115
116
117
|
# File 'lib/ruby-fire.rb', line 109
def initialize(rec = nil, program_name: nil, &block)
if rec.is_a?(Symbol)
main = TOPLEVEL_BINDING.receiver
rec = (main.method(rec) if main.private_methods.include?(rec) || main.methods.include?(rec))
end
@rec = rec || block || TOPLEVEL_BINDING
@program_name = program_name
@current_run_params = nil
end
|
Class Method Details
.fire(*args, **kwargs, &block) ⇒ Object
12
13
14
15
|
# File 'lib/ruby-fire.rb', line 12
def fire(*args, **kwargs, &block)
res = new(*args, **kwargs, &block).run
puts res.is_a?(String) ? res : res.pretty_inspect unless res.nil?
end
|
.method_arguments(func_parameters, params) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/ruby-fire.rb', line 28
def method_arguments(func_parameters, params) args = []
kwargs = nil
skip_opts = []
func_parameters.each do |type, name, default|
case type
when :req
args << params.delete(name) if params.include?(name)
when :opt
if params.include?(name)
args << skip_opts.shift until skip_opts.empty?
args << params.delete(name)
else
skip_opts << default
end
when :rest
args.push(*(params.delete(name) || []))
when :keyreq, :key
(kwargs ||= {})[name] = params.delete(name) if params.include?(name)
when :keyrest
params.each_key do |key|
(kwargs ||= {})[key] = params.delete(key)
end
end
end
[args, kwargs]
end
|
.new_method?(func) ⇒ Boolean
57
58
59
|
# File 'lib/ruby-fire.rb', line 57
def new_method?(func)
func.is_a?(Method) && func.owner.is_a?(Class) && func.name == :new
end
|
.parameters_call(func, func_parameters, params, error = true) ⇒ Object
17
18
19
20
21
22
23
24
25
26
|
# File 'lib/ruby-fire.rb', line 17
def parameters_call(func, func_parameters, params, error = true)
args, kwargs = method_arguments(func_parameters, params)
raise ArgumentError, "unknown keywords: #{params.keys.join(', ')}" if error && !params.empty?
if kwargs
func.call(*args, **kwargs)
else
func.call(*args)
end
end
|
.trace_parameters(trace_func) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
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
97
98
99
100
101
102
103
104
105
106
|
# File 'lib/ruby-fire.rb', line 61
def trace_parameters(trace_func) is_proc = trace_func.is_a?(Proc)
func = new_method?(trace_func) ? trace_func.receiver.instance_method(:initialize) : trace_func
mock_kwargs = nil
func.parameters.each do |type, name|
(mock_kwargs ||= {})[name] = nil if type == :keyreq
end
mock_arg_size = (func.arity.negative? ? ~func.arity : func.arity) - (mock_kwargs ? 1 : 0)
mock_args = Array.new(mock_arg_size)
[].tap do |results|
counts = { call: 0, b_call: -1, c_call: -1 }
trace = TracePoint.new(:call, :b_call, :c_call) do |tp|
count = counts[tp.event] += 1
next unless count.positive?
if is_proc
next unless tp.event == :b_call
vars = tp.binding.local_variables
next unless func.parameters.all? { |_type, name| vars.include?(name) }
else
next if tp.event == :b_call
next unless tp.defined_class == func.owner && tp.callee_id == func.name
end
func.parameters.each do |type, name|
opt = %i[opt key].include?(type)
results << [type, name, opt && name ? tp.binding.local_variable_get(name) : nil]
end
raise TracePointTerminate
end
trace.enable do
if mock_kwargs
trace_func.call(*mock_args, **mock_kwargs)
else
trace_func.call(*mock_args)
end
end
rescue TracePointTerminate end
end
|
Instance Method Details
#parse!(argv = ARGV) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
209
210
211
212
213
214
215
216
217
218
219
220
221
|
# File 'lib/ruby-fire.rb', line 209
def parse!(argv = ARGV) @opt = parser
@params = {}
args = @opt.parse!(argv, into: @params)
if !args.empty? || @current_run_params.nil? || self.class.new_method?(@current_run_params.first)
raise XOptionParser::InvalidArgument
end
rescue XOptionParser::ParseError => e
@current_run_params&.last&.each do |key|
@opt = @opt.instance_variable_get(:@commands)[key.to_s].block.call
end
raise e
end
|
#parser ⇒ Object
119
120
121
122
123
124
|
# File 'lib/ruby-fire.rb', line 119
def parser
XOptionParser.new do |opt|
opt.program_name = @program_name if @program_name
define_options(opt, [], @rec)
end
end
|
#run(*args) ⇒ Object
235
236
237
238
239
240
|
# File 'lib/ruby-fire.rb', line 235
def run(*args)
run!(*args)
rescue XOptionParser::ParseError
puts @opt.help
exit
end
|
#run!(*args) ⇒ Object
230
231
232
233
|
# File 'lib/ruby-fire.rb', line 230
def run!(*args)
parse!(*args)
current_run
end
|