ruby - 带有自定义命令的 Ruby 自定义 shell
问题描述
我想编写一个 Ruby 程序,它基本上是一个带有自定义命令的 shell。这意味着在调用“ ruby app.rb ”之后,用户将进入一个支持我编写的特殊命令的 shell。
我曾经loop do ... end
创建一个处理用户输入的基本循环。我还使用了一个字符串数组来存储所有可用的命令,以及一个包含每个可用命令的帮助消息的哈希表。但这非常麻烦。
我想知道如何优雅地定义带有标志的自定义命令,其中一些是强制性的(例如 create -f "~/file.txt" --READONLY -v)。不仅如此,我还需要我的 shell 的“帮助”命令来输出关于每个自定义命令的信息,包括标志,并有一个列出每个可用命令的“菜单”命令。作为最后的手段,我想简单地为每个命令创建一堆 .rb 文件,然后使用 OptionParser 作为标志和参数,因为我不知道如何让 OptionParser 使用函数而不是文件。
到目前为止,这是我想出的:
class Shell
@@input = ""
# List of all commands
@@commands = [
"help",
"exit"
]
# Help messages associated with commands
@@help_strings = Hash[
"help" => "Outputs this info.",
"exit" => "Closes the program."
]
def self.start
# bash clear screen command
system("clear")
loop do
print (">> ")
input = gets.chomp
case input
when "help"
for com in @@commands
puts("#{com}: #{@@help_strings[com]}")
end
when "exit"
# bash clear screen command
system("clear")
break
else
puts("Unknown commands: #{input}")
puts("Type \"help\" for more info.")
end
end
end
end
解决方案
创建一个健壮的REPL有很多工作要做,但是您可以采取一些优化措施来简化您在此处获得的内容。
- 创建一个
Runner
包含所有命令的单独类。使用methods
andinstance_methods
获取支持的命令列表,而无需维护单独的列表。 - 检查是否支持命令,然后直接调用方法而不是使用
case
语句。 - 捕获
ctrl+c
以干净地退出循环。
class Shell
class Runner
def supported_method?(method)
# This will return an array of the instance methods that are not provided by ancestors
(methods - Object.instance_methods).include?(method.to_sym)
end
def help
puts "[TODO: Help info]"
end
def exit
system "clear"
end
end
def self.start
runner = Runner.new
loop do
print (">> ")
input = gets.chomp
if runner.supported_method?(input)
runner.send(input)
else
puts("Unknown commands: #{input}\nType \"help\" for more info.")
end
end
rescue SystemExit, Interrupt, IRB::Abort
puts "\nShutting down."
end
end
推荐阅读
- php - ffmpeg 命令通过命令行执行,而不是通过 PHP 脚本
- android - 在片段中定义 RecyclerView (Android Studio)
- string-aggregation - 我不知道如何使用 string_agg 进行排序
- java - 为什么 okhttp 程序不会卡在 while(true) 中?
- r - 根据其他两列的聚合添加新列
- r - 在 R 中使用 cppRouting 包的 Djikstra 方法
- r - 如何在 geom_segment 中获取类型 T 箭头?
- reactjs - Babel 需要未使用的模块?
- python - 如何访问本体中节点的层次信息,为不同层次的类分配不同的权重?
- python - 根据条件选择数据框值