Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建交互式ruby控制台应用程序_Ruby_Console_Interactive - Fatal编程技术网

创建交互式ruby控制台应用程序

创建交互式ruby控制台应用程序,ruby,console,interactive,Ruby,Console,Interactive,我想制作一个交互式应用程序,用户可以在其中启动它,并可以通过键入命令(某种shell)来完成各种任务 示例: /myapp.rb 应用程序说你好 命令: 帮助-显示关于命令的帮助 打开-打开任务 行动 开始>帮助打开 打开 打开指定的任务 开始>打开某物 某事>做某事 成功! 某物>(此处光标闪烁) 我搜索了一下,但找不到任何ruby gems,我可以专门用于控制台交互,所以我要做我自己的 我看了看,但那不完全是我想要的,也许我可以用它,但不确定 它可能看起来像: 类任务 属性读取器:已打

我想制作一个交互式应用程序,用户可以在其中启动它,并可以通过键入命令(某种shell)来完成各种任务

示例:

/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