调用“字符串”的私有方法“ puts”:字符串(NoMethodError)

时间:2019-04-12 05:16:31

标签: ruby

我正在使用ruby: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)

2 个答案:

答案 0 :(得分:3)

@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#scanArray#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,所以FileIO继承了这些方法。

答案 1 :(得分:1)

此语句line.puts new_line导致错误。

我假设您要在此处实现的目的是将new_line写入输出文件,并且可能您认为line是一个File对象,但不是,因为line是{{ 1}},其中包含从输入文件读取的每一行。此外,您的File.open方法仅为string,因此您无法在该文件上写入。

因此,我建议您首先将每个read-only state存储在列表中,然后在处理完输入文件中的所有行之后,进行另一个循环,在该循环中您将覆盖文件以反映得到的结果。

new_line