简体   繁体   English

私有方法“ puts”需要“ string”:String(NoMethodError)

[英]private method `puts' called for “string”:String (NoMethodError)

I am using ruby: 1.9.3 我正在使用ruby:1.9.3

File named as restaurant.txt which has the data like this: 名为restaurant.txt的文件,其数据如下:

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

Now what I have to do is to take the last string and remove the existing line. 现在,我要做的是获取最后一个字符串并删除现有行。 output file have to be the same file and should look like: 输出文件必须是相同的文件,并且应类似于:

 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

I am getting the error: 我收到错误消息:

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

@Whooper has identified the problem with your code. @Whooper已确定您的代码有问题。 I have therefore chosen to suggest another approach to constructing the desired file. 因此,我选择建议另一种构建所需文件的方法。

Let's first construct a file that contains the string given in your example. 让我们首先构造一个包含示例中给出的字符串的文件。

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)

Confirm its contents: 确认其内容:

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"

You can read the file and use String#scan with a simple regular expression and Array#join to construct the string you wish to keep. 您可以读取文件,并使用带有简单正则表达式的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"

The regular expression reads, "match a double quote followed by all characters other than a pipe ( "|" ) to the end of the line". 正则表达式的内容为:“将双引号与除管道( "|" )以外的所有其他字符匹配到该行的末尾”。 Each match will begin with the first double-quote following the last pipe in the line. 每次匹配均以该行最后一个管道之后的第一个双引号开头。

Lastly, write s back to the same file, overwriting its contents. 最后,将s写回到同一文件,覆盖其内容。

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

Have a look. 看一看。

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

The use of IO::read is sometimes referred to as gulping a file (as a string). IO :: read的使用有时称为吞入文件 (作为字符串)。 1 That's fine as long as the file is not too large. 1只要文件不是太大就可以了。 If it's a very large file it may be necessary to read the file line-by-line, modify the line and then write that to a temporary file. 如果文件很大,则可能需要逐行读取文件,修改该行,然后将其写入临时文件。 When the temporary file is complete the original file can be deleted and, if desired, the temporary file can be renamed to the name of the original file. 临时文件完成后,可以删除原始文件,如果需要,可以将临时文件重命名为原始文件的名称。 You could do that as follows. 您可以按照以下步骤进行操作。

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)

Confirm: 确认:

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

1 I don't know if there is a comparable term for the use of IO#write ; 1我不知道是否有使用IO#write的可比术语; perhaps disgorging a string into a file . 也许将字符串分解为文件 Though read and write are IO (class) methods, they are commonly involked on the class File . 虽然readwriteIO (类)方法,它们通常involked的类File That's OK because File.superclass #=> IO , so File inherits those methods from IO . 可以,因为File.superclass #=> IO ,所以FileIO继承了这些方法。

This statement line.puts new_line causes the error. 此语句line.puts new_line导致错误。

I am assuming that what you want to achieve here is to write new_line to your output file and maybe you thought that line is a File object, which is not, because line is a string which contains each line read from your input file. 我假设您要在此处实现的目的是将new_line写入输出文件,也许您认为line是一个File对象,而不是,因为line是包含从输入文件读取的每一行的string Besides, your File.open method is only read-only state so you cannot write on that file. 此外,您的File.open方法read-only state因此您无法在该文件上写入。

So I suggest that you store first each new_line in a list then after you finished processing all lines from your input file, have another loop where you will overwrite your file to reflect the results you got. 因此,我建议您首先将每个new_line存储在一个列表中,然后在处理完输入文件中的所有行之后,进行另一个循环,在该循环中您将覆盖文件以反映得到的结果。

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"

new_lines = []
File.open(foodie, "r+").each do |line|
  new_lines.push(line.split("|")[-1])
end

File.open(foodie, "w+") do |file|
  new_lines.each { |element| file.puts(element) }
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM