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

时间:2017-02-02 22:50:09

标签: ruby oop conceptual

我对ruby非常陌生,所以请耐心等待......在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和一些常见的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)错误。但是,字符串永远不会是空的,所以检查条件对我来说没有意义。

2 个答案:

答案 0 :(得分:2)

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,则至少会有换行符。

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

答案 1 :(得分:1)

如果按CTRL + D ,

gets可以返回nil(至少在irb中)

CTRL + D是unix信号,这意味着我已完成输入或文件结束。

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

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

这就是为什么他第一次测试nil,然后调用chomp!

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