首页 > 解决方案 > 为“字符串”调用私有方法“puts”:字符串(NoMethodError)

问题描述

我正在使用红宝石:1.9.3

名为 restaurant.txt 的文件,其数据如下:

|"Aloo Fry"| "Carbohydrates bahut hai" | "Nahi Khana"
|"Moong"| "protein bahut hai" | "Khana Hai"
|"Egg"|"Protein hai but non veg"| "Nahi khana hai"

现在我要做的是取出最后一个字符串并删除现有的行。输出文件必须是同一个文件,并且应该如下所示:

Nahi Khana 
Khana Hai 
Nahi Khana hai
if ARGV.length != 1
  puts "Input only the one file at a time"
  exit
end
foodie = ARGV[0]
puts "you have entered file: #{foodie}"
puts "Hold your horses... we are processing"
File.open(foodie, "r+").each do |line|
  new_line = line.split("|")[-1]
  puts new_line
  line.puts new_line
end

我收到错误消息:

private method `puts' called for "Nahi Khana":String (NoMethodError)

标签: ruby

解决方案


@Whooper 已发现您的代码存在问题。因此,我选择提出另一种构建所需文件的方法。

让我们首先构建一个包含示例中给出的字符串的文件。

FName = 'temp'
str =<<END
|"Aloo Fry"| "Carbohydrates bahut hai" | "Nahi Khana"
|"Moong"| "protein bahut hai" | "Khana Hai"
|"Egg"|"Protein hai but non veg"| "Nahi khana hai"
END

File.write(FName, str)
  #=> 149 (characters)

确认其内容:

puts File.read(FName)
|"Aloo Fry"| "Carbohydrates bahut hai" | "Nahi Khana"
|"Moong"| "protein bahut hai" | "Khana Hai"
|"Egg"|"Protein hai but non veg"| "Nahi khana hai"

您可以读取文件并使用带有简单正则表达式的String#scan和Array#join来构造您希望保留的字符串。

s = File.read(FName).scan(/\"[^|]+$/).join("\n")
  #=> "\"Nahi Khana\"\n\"Khana Hai\"\n\"Nahi khana hai\"\n" 
puts s
"Nahi Khana"
"Khana Hai"
"Nahi khana hai"

正则表达式读取,“匹配双引号后跟除管道 ( "|") 之外的所有字符到行尾”。每场比赛都将从该行最后一个管道之后的第一个双引号开始。

最后,写s回同一个文件,覆盖其内容。

File.write(FName, s)
  #=> 42

看一看。

puts File.read(FName)
"Nahi Khana"
"Khana Hai"
"Nahi khana hai"

IO::read的使用有时被称为吞咽文件(作为字符串)。1只要文件不是太大就可以。如果它是一个非常大的文件,可能需要逐行读取文件,修改该行,然后将其写入临时文件。当临时文件完成时,可以删除原始文件,如果需要,可以将临时文件重命名为原始文件的名称。您可以按如下方式进行。

TMP_FName = 'tmp'

f = File.open(TMP_FName, 'w')
File.foreach(FName) do |line|
  f.puts line.scan(/\"[^|]+$/).join("\n")
end
f.close
File.delete(FName)
File.rename(TMP_FName, FName)

确认:

puts File.read(FName)
"Nahi Khana"
"Khana Hai"
"Nahi khana hai"

1 不知道IO#write的使用有没有类似的说法;可能将字符串放入文件中。虽然readwriteIO(类)方法,但它们通常在类中被调用File。没关系,因为File.superclass #=> IO, 所以File继承了这些方法IO


推荐阅读