【问题标题】:Ruby - How to test for nil or empty string from console(stdin)Ruby - 如何从控制台(stdin)测试 nil 或空字符串
【发布时间】:2017-02-02 22:50:08
【问题描述】:

我对 ruby​​ 很陌生,所以请耐心等待...

str = gets
exit if str.nil? || str.empty?
str.chomp!
temp, scale = str.split(" ")

我的查询如下:

鉴于gets 只会返回并包括cr,为什么要测试空字符串?

如果您测试以下内容:

puts nil.to_s.empty?
puts "".to_s.empty?
puts "".length            #the empty string      : equates to 0
puts nil.to_s.length      #the 'to string' method: equates to 0

两者都将评估为真并且长度为零。但是,如果只有 cr,流中唯一的就是 回车 本身。 str 在下面的长度如果你只是按回车键就会有 1。

print "enter a string or hit the enter key : "
str = gets
puts str.length
puts str

此外,ruby 中的nil 是一个对象。我到底是如何从stdin 捕获那个的?

我现在看到chomp! 在文本中放错了位置,作者的错误不是我的:

str = gets
str.chomp!
exit if str.nil? || str.empty? #test for zero length string will now work
temp, scale = str.split(" ")

当然,我来自 java 和 一些 common lisp,因此可能过于陈旧而无法理解这一点,但我仍然不明白nil 的测试在这种情况下是否合适。也许流中存在一些概念上的差异,这些差异比我的阅读要远。提前致谢。

编辑:

为了消除一些混乱,这里重新编写了代码,仅更改了 chomp! 语句的位置:

#temperature-converter.rb
#code changed by poster, otherwise as written by author
print "Please enter a temperature and scale (C or F) : "
STDOUT.flush   #self explanatory....
str = gets
str.chomp!     #new placement of method call -- edit by poster
exit if str.nil? || str.empty?
#chomp! original position -- by author
temp, scale = str.split(" ")
abort "#{temp} is not a valid number." if temp !~ /-?\d+/
temp = temp.to_f
case scale
    when "C", "c"
        f = 1.8 * temp + 32
    when "F", "f"
        c = (5.0/9.0) * (temp - 32)
else
abort "Must specify C or F."
end
if f.nil?
    puts "#{c} degrees C"
else
    puts "#{f} degrees F"
end

还有输出:

=>ruby temperature-converter.rb
Please enter a temperature and scale (C or F) : 30 c
86.0 degrees F
=>ruby temperature-converter.rb
Please enter a temperature and scale (C or F) : j c
j is not a valid number.
=>ruby temperature-converter.rb
Please enter a temperature and scale (C or F) : 30 p
Must specify C or F.
=>ruby temperature-converter.rb
Please enter a temperature and scale (C or F) :    #just the enter key
=>                                                 #did this just exit?!

但是我选择的答案是正确的,如果你使用 Ctl+D(U) 或 Ctl+Z(W) 可以模拟 eof 并抛出 in '<main>': undefined method 'chomp!' for nil:NilClass (NoMethodError) is 错误。尽管如此,字符串永远不会为空,所以检查条件对我来说没有意义。

【问题讨论】:

    标签: ruby oop conceptual


    【解决方案1】:

    documentationgets可以返回一个字符串或者nil

    返回(并分配给 $_)文件列表中的下一行 ARGV(或 $*),如果没有文件,则来自标准输入 命令行。在文件末尾返回 nil。

    来自标准输入

    使用 CTRL+D 查看@MarkoAvlijaš'answer

    来自 ARGV

    您可以创建一个名为empty.txt 的空文件,然后启动:

    ruby your_script.rb empty.txt
    

    什么都不应该发生。

    如果你删除第二行:

    your_script.rb:3:in `<main>': undefined method `chomp!' for nil:NilClass (NoMethodError)
    

    我看不出str 在上面的代码中怎么可能是空的。如果str 不是nil,至少会有一个换行符。

    请注意,如果您在检查str 不是nil 之前使用chomp!,您可能会得到NoMethodError

    【讨论】:

    • 谢谢,在阅读了提供的文档后,我检查了并且您的评估是正确的。咻。
    • 不客气。感谢 Marko 找到有关 CTRL+D
    【解决方案2】:

    gets 可以在按下 CTRL+D 时返回 nil(至少在 irb 中)

    CTRL+D 是 unix 信号,表示我输入完毕或文件结束。

    这就是为什么书中的代码是正确的。在这种情况下,您的版本将生成 NoMethodError

    gets.chomp!
    NoMethodError: undefined method `chomp!' for nil:NilClass
    

    这就是为什么他首先测试nil,然后调用chomp!

    如果您想要更多新手友好提示,请查看此答案的编辑历史记录。我已将其删除,因为它们与此答案无关。

    【讨论】:

    • Ctrl+D 的不错发现。我不明白你对chomp! 的看法。
    • 看看他帖子的结尾,他按照自己的想法发布了代码。基本上是gets.chomp!
    • 是的。我看不出chomp! 可能返回nil 是如何相关的。
    猜你喜欢
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 2013-12-18
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多