【问题标题】:Why Can't You See Return Value of a Ruby Script in Command Line?为什么在命令行中看不到 Ruby 脚本的返回值?
【发布时间】:2018-01-18 03:16:03
【问题描述】:

我的问题是对这个问题的跟进:No return on command line when running Ruby script 因为答案没有提供解释:

获取以下文件,script.rb:

def hello(names)
  names.map {|name| "#{name} is awesome!"}
end

hello(["mark", "tony", "scott"])

在命令行中使用ruby script.rb 执行文件时,不会出现以下函数的返回值。但是,在 IRB 中测试该方法或使用 PRY 放入代码中会输出显式返回值。为什么通过脚本执行看不到返回值?

附:我知道使用 puts 会将代码输出到终端,但我对为什么不输出 return 值感兴趣。

【问题讨论】:

  • 是否有一种语言确实以这种方式将最后一个返回值显示到命令行?

标签: ruby shell irb


【解决方案1】:

因为 IRBPry 都是 REPL's

REPL 代表:readevaluateprintloop。这正是 PryIRB 正在做的事情。

他们将首先读取您的输入,评估您的代码,打印代码执行的结果,然后重新开始。

【讨论】:

    【解决方案2】:

    Ruby 脚本不能像您希望的那样直接返回值,Bash shell 的工作方式相同,Bash 函数不能直接返回字符串。您可以返回一个字符串(带标准输出)并将其分配给变量。

    ~:$~  cat scr.rb
    ~:$~  puts "Something here"
    ~:$~  echo $(ruby ./scr.rb) 
    Something here
    ~:$~  myvar=$(echo $(ruby ./scr.rb))
    ~:$~  echo $myvar
    Something here
    

    【讨论】:

      【解决方案3】:

      这真的很简单:Bash(或您使用的任何 shell)和 Ruby 是不同的编程语言。 Bash 对 Ruby 一无所知。它不知道什么是“Ruby 返回”,它不知道什么是“Ruby 数组”,它不知道什么是“Ruby 字符串”。因此,您只是不可能将 Ruby 对象返回给 Bash。

      实际上,shell 通常只是使用一些操作系统函数来执行 Ruby 脚本(例如经典的 forkexec 或类似 vforkclone 的东西)。如果你想以这种方式返回值,操作系统内核必须知道曾经发明的每一种编程语言的语义,以及未来将要发明的每一种编程语言。这是不可行的。

      注意命令可以返回一个值给shell,即一个0到255之间的整数,作为状态码(0表示“成功”,非零意思是“错误”),你可以通过调用Kernel#exit来设置返回值。

      【讨论】:

        【解决方案4】:

        当我开始编码时,我自己也曾经有过同样的问题。如果您仔细查看您的代码,您会发现它为什么不打印任何内容。您实际上并没有在您的代码中询问它。想象一下有一个包含数千行的巨大脚本,并且您想要执行它。如果ruby myscript.rb 的工作方式与 REPL 相同,您将获得数百万个毫无意义的输出。

        此外,如果您确实希望它以这种方式工作,您可以只需要 REPL 会话中的脚本 (require_relative 'your_script'),然后如果您调用您的函数 hello,它将按照您描述的方式工作。

        【讨论】:

          【解决方案5】:

          我可以使用ruval gem。它评估每个语句并返回其值。

          $ ruval names.rb
          def hello(names)
            names.map {|name| "#{name} is awesome!"}
          end
          => hello
          hello(["mark", "tony", "scott"])
          => ["mark is awesome!", "tony is awesome!", "scott is awesome!"]
          

          【讨论】:

            猜你喜欢
            • 2018-04-21
            • 2011-03-10
            • 2011-01-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-05-15
            • 2012-01-17
            相关资源
            最近更新 更多