Ruby - 如何从控制台 (stdin) 测试 nil 或空字符串

Ruby - How to test for nil or empty string from console(stdin)

我是 ruby 的新手,所以请耐心等待...在 Ruby 上的文本中有一个代码示例可以执行此操作:

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

我的查询如下:

鉴于 gets 只会 return 直到并包括 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,流中唯一的东西就是 车厢 return 本身。 str 如果您直接按回车键,则以下内容的长度为 1。

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

此外,ruby中的nil是一个对象。我怎么想从 stdin?

捕获 that

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

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

当然,我来自 java 和 一些 普通的 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 错误。尽管如此,该字符串永远不会为空,因此检查条件对我来说没有意义。

documentationgets可以return一个字符串或者nil

Returns (and assigns to $_) the next line from the list of files in ARGV (or $*), or from standard input if no files are present on the command line. Returns nil at end of file.

来自标准输入

使用 CTRL+D 查看@MarkoAvlijaš'

从 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.

gets 如果按 CTRL+D 可以 return nil(至少在 irb 中)

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

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

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

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

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