5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
55
56
57
|
# File 'lib/autoargs.rb', line 5
def self.run(method)
caller_file = caller[0].split(":")[0]
if caller_file == $0
ast = Parser::CurrentRuby
.parse(File.read(caller_file))
.children
.select do |node| node.type == :def end
.map(&:children)
.select do |name, _| name == method.name end[0]
abort("No top level method named " + method.name.to_s + " found.") if ast.nil?
all_args = ast[1].children
args = all_args
.select do |arg| arg.type == :arg end
.map do |arg| arg.children[0] end
optargs = all_args
.select do |arg| arg.type == :optarg end
.map do |arg| { :name => arg.children[0], :default => arg.children[1].children[0] } end
kwoptargs = Hash[
all_args
.select do |arg| arg.type == :kwoptarg end
.map do |arg| [arg.children[0], arg.children[1].children[0]] end
]
argv_args = ARGV[0 ... args.length]
argv_optargs = ARGV[args.length ... args.length + optargs.length]
argv_kwoptargs = Hash[
(ARGV[args.length + optargs.length .. -1] || [])
.each_slice(2)
.map do |name_with_prefix, value|
abort("Expected argument " + name_with_prefix + " to start with --.") unless name_with_prefix.start_with?("--")
name = name_with_prefix[2 .. -1]
abort(name + " is not an option.") unless kwoptargs.has_key?(name.to_sym)
[name.to_sym, value]
end
]
if argv_args.length < args.length
abort([[caller_file],
args.map do |arg| "<" + arg.to_s + ">" end,
optargs.map do |optarg| "[" + optarg[:name].to_s + "=" + optarg[:default].inspect + "]" end,
kwoptargs.map do |name, default| "[--" + name.to_s + " " + default.inspect + "]" end
].flatten(1).join(" "))
end
method.call(*ARGV.slice(0, args.length + optargs.length), **argv_kwoptargs)
end
end
|