创建交互式ruby控制台应用程序
我想制作一个交互式应用程序,用户可以在其中启动它,并可以通过键入命令(某种shell)来完成各种任务 示例:创建交互式ruby控制台应用程序,ruby,console,interactive,Ruby,Console,Interactive,我想制作一个交互式应用程序,用户可以在其中启动它,并可以通过键入命令(某种shell)来完成各种任务 示例: /myapp.rb 应用程序说你好 命令: 帮助-显示关于命令的帮助 打开-打开任务 行动 开始>帮助打开 打开 打开指定的任务 开始>打开某物 某事>做某事 成功! 某物>(此处光标闪烁) 我搜索了一下,但找不到任何ruby gems,我可以专门用于控制台交互,所以我要做我自己的 我看了看,但那不完全是我想要的,也许我可以用它,但不确定 它可能看起来像: 类任务 属性读取器:已打
/myapp.rb
应用程序说你好
命令:
帮助-显示关于命令的帮助
打开-打开任务
行动
开始>帮助打开
打开
打开指定的任务
开始>打开某物
某事>做某事
成功!
某物>(此处光标闪烁)
我搜索了一下,但找不到任何ruby gems,我可以专门用于控制台交互,所以我要做我自己的
我看了看,但那不完全是我想要的,也许我可以用它,但不确定
它可能看起来像:
类任务
属性读取器:已打开的属性读取器任务
描述“打开”,“打开指定任务”
def打开(参数)
结束
desc“输入/输出怎么办,还有什么其他建议吗?您需要的是–阅读→ 评估→ 打印循环
例如,IRB实现了Ruby语言的REPL
下面是应用程序REPL的一个非常简单的实现:
loop do
Application::Console.prompt.display
input = gets.chomp
command, *params = input.split /\s/
case command
when /\Ahelp\z/i
puts Application::Console.help_text
when /\Aopen\z/i
Application::Task.open params.first
when /\Ado\z/i
Application::Action.perform *params
else puts 'Invalid command'
end
end
\A
和\z
分别匹配字符串的开头和结尾。类MyAPI
class MyAPI
def self.__is__(text)
@__is__ = text
end
def self.method_added(method)
@__help__ ||= {}
@__help__[method.to_s] = @__is__
@__is__ = nil
end
def self.help(of)
@__help__[of]
end
__is__ "open file <file>"
def open(file)
#...
end
__is__ "do X"
def do(*params)
#...
end
__is__ "calls help, use help <command>"
def help(*args, &block)
self.class.help(*args, &block)
end
end
MyAPI.new(...).pry
定义自我是(文本)
@__是文本吗
结束
添加了定义自身方法(方法)
@__help| |={}
@__help_uuu[method.to_us]=@uu是__
@__是u uu=nil
结束
def自助(of)
@__帮助
结束
__是否为“打开文件”
def打开(文件)
#...
结束
__是“dox”
def do(*参数)
#...
结束
__是“呼叫帮助,使用帮助”
def帮助(*参数和块)
self.class.help(*args和block)
结束
结束
MyAPI.new(…).pry
或者你可以使用撬命令,但这会破坏
图灵完整性。帮助可以使用命令实现,正如我所说的
不确定我的方法效果如何。这些方法需要改进
代码防御。我记不起如何使用类变量:-/您也可以尝试。(从文档中):
创建和启动自定义shell非常简单:
require 'ripl'
# Define plugins, load files, etc...
Ripl.start
项目网站上有一个完整的ripl插件列表,以及使用ripl的控制台应用程序列表。好的,所以我创建了这个库,用于在ruby中创建控制台应用程序。实际上,这是很久以前的事了,但只是刚刚决定发布它。如果与HighLine和Readline一起使用,它确实支持自动完成
当我写它的时候,没有任何文档,也没有测试/规范,但现在我做了一些。仍然没有太多,但对于开始应该是可以的
那么宝石和
代码在GitHub上,这里是看看cliqr
ruby gem。它看起来正是您所需要的。这里是带有描述性自述的GitHub链接:
它可以直接执行命令,也可以在内置shell中执行命令
以下是git repo的一个测试用例:
it 'can execute a sub action from shell' do
cli = Cliqr.interface do
name 'my-command'
handler do
puts 'base command executed'
end
action :foo do
handler do
puts 'foo executed'
end
action :bar do
handler do
puts 'bar executed'
end
end
end
end
with_input(['', 'my-command', 'foo', 'foo bar', 'foo bar help']) do
result = cli.execute %w(my-command shell), output: :buffer
expect(result[:stdout]).to eq <<-EOS
Starting shell for command "my-command"
my-command > .
base command executed
my-command > my-command.
base command executed
my-command > foo.
foo executed
my-command > foo bar.
bar executed
my-command > foo bar help.
my-command foo bar
USAGE:
my-command foo bar [actions] [options] [arguments]
Available options:
--help, -h : Get helpful information for action "my-command foo bar" along with its usage information.
Available actions:
[ Type "my-command foo bar help [action-name]" to get more information about that action ]
help -- The help action for command "my-command foo bar" which provides details and usage information on how to use the command.
my-command > exit.
shell exited with code 0
EOS
end
end
它“可以从shell执行子操作”do
cli=Cliqr.do接口
命名“我的命令”
处理程序
将“基本命令已执行”
结束
行动:富多
处理程序
执行“foo”
结束
行动:酒吧
处理程序
将“bar执行”
结束
结束
结束
结束
使用输入(['''my command','foo','foo bar','foo bar help'])执行
结果=cli.execute%w(我的命令shell),输出::缓冲区
期望(result[:stdout])均衡我的命令。
已执行基本命令
我的命令>foo。
傅执行
我的命令>foo-bar。
执行的酒吧
我的命令>foo-bar帮助。
我的命令foo-bar
用法:
我的命令foo-bar[操作][选项][参数]
可用选项:
--帮助,-h:获取操作“my command foo bar”的有用信息及其使用信息。
可采取的行动:
[键入“my command foo bar help[操作名称]”以获取有关该操作的详细信息]
help——命令“my command foo bar”的帮助操作,提供有关如何使用该命令的详细信息和用法信息。
我的命令>退出。
shell已退出,代码为0
EOS
结束
结束
是一个非常好的工具,可以轻松地完成这类工作。您有很多工具可以单独使用或与完整的工具包一起使用。您可以使用颜色、提示、执行shell本机、与屏幕交互、打印表、进度条和许多其他有用的命令行元素,这些都可以通过goop api轻松实现
特别是对于请求用户输入非常有用
您提出的案例的一个简单示例:
require 'tty-prompt'
require 'pastel'
prompt = TTY::Prompt.new
loop do
cmd, parms* = prompt.ask('user@machine$ ').split /\s/
case cmd
when "hola"
puts "Hola amigo " parms
when "exit"
break if prompt.yes?('Do you really want to exit?')
end
end
应该是ruby还是您自己的语法?您所说的ruby或自己的语法是什么意思?:|如果您是指使用IRB,那么这不是一个选项…为什么不?它免费为您提供图灵完整性。因为它执行ruby代码,但在我的情况下,只允许一些特定的“命令”“,键入错误的语法不应引发异常,也不应存在重新定义或重写这些命令的方法…这是安全问题吗?您还可以钩住pry
查找语法错误。重新定义不应该是个问题,因为你需要知道它是如何工作的。当你期望你的用户在当前的敏感时代使用命令行而不是GUI时,我相信他们会有一点能力。但这是你的选择,享受重新实现很多东西的乐趣,而不是在对象上调用pry。您还可以免费获得一个API。好的,感谢您展示了我如何实现控制台类方法“start”的一种方法:@davispuh我忘记了提示–使用改进的实现更新了答案。您的start
方法应该只包含循环。我接受了这个答案,因为它建议通过显示实现的一部分来自己创建,所以我将创建自己的CLI,特别是针对我的所有需要…Console
是Ruby附带的类吗?如果是这样,我需要什么才能得到它?@LironYahdav不,这个类是我为这个答案而编写的API的一部分。假设Console
包含应用程序的所有代码
it 'can execute a sub action from shell' do
cli = Cliqr.interface do
name 'my-command'
handler do
puts 'base command executed'
end
action :foo do
handler do
puts 'foo executed'
end
action :bar do
handler do
puts 'bar executed'
end
end
end
end
with_input(['', 'my-command', 'foo', 'foo bar', 'foo bar help']) do
result = cli.execute %w(my-command shell), output: :buffer
expect(result[:stdout]).to eq <<-EOS
Starting shell for command "my-command"
my-command > .
base command executed
my-command > my-command.
base command executed
my-command > foo.
foo executed
my-command > foo bar.
bar executed
my-command > foo bar help.
my-command foo bar
USAGE:
my-command foo bar [actions] [options] [arguments]
Available options:
--help, -h : Get helpful information for action "my-command foo bar" along with its usage information.
Available actions:
[ Type "my-command foo bar help [action-name]" to get more information about that action ]
help -- The help action for command "my-command foo bar" which provides details and usage information on how to use the command.
my-command > exit.
shell exited with code 0
EOS
end
end
require 'tty-prompt'
require 'pastel'
prompt = TTY::Prompt.new
loop do
cmd, parms* = prompt.ask('user@machine$ ').split /\s/
case cmd
when "hola"
puts "Hola amigo " parms
when "exit"
break if prompt.yes?('Do you really want to exit?')
end
end