如何编写函数返回文件?

时间:2015-04-02 14:57:13

标签: ruby file

我创建了一个名称生成器。

当我尝试将结果保存到文件时,它会输入一个空行或者说“#34; true"”。我需要它来放置并说出文件中生成的名称。

这是我的代码:

def generate_secondname
  dice = rand
  if dice > 0.01 && dice < 0.09
    print "saunders"
  elsif dice > 0.10 && dice < 0.19
    print "winters"
  elsif dice > 0.20 && dice < 0.29
    print "burgess"
  elsif dice > 0.30 && dice < 0.39
    print "webster"
  elsif dice > 0.40 && dice < 0.49
    print "holister"
  elsif dice > 0.50 && dice < 0.59
    print "johnson"
  elsif dice > 0.60 && dice < 0.69
    print "green"
  elsif dice > 0.70 && dice < 0.79
    print "paul"
  elsif dice > 0.80 && dice < 0.89
    print "hendrix"
  else dice > 0.90 && dice < 0.99
  print "luster"
  end
end


def generate_name(generate_secondname)
  dice = rand
  if (dice >= 0.01) && (dice <= 0.09)
    print "ashley"
    print "#{generate_secondname}"
  elsif dice > 0.10 && dice < 0.19
    print "george"
    print "#{generate_secondname}"
  elsif dice > 0.20 && dice < 0.29
    print "nick"
    print "#{generate_secondname}"
  elsif dice > 0.30 && dice < 0.39
    print "sam"
    print "#{generate_secondname}"
  elsif dice > 0.40 && dice < 0.49
    print "roland"
    print "#{generate_secondname}"
  elsif dice > 0.50 && dice < 0.59
    print "preston"
    print "#{generate_secondname}"
  elsif dice > 0.60 && dice < 0.69
    print "brandon"
    print "#{generate_secondname}"
  elsif dice > 0.70 && dice < 0.79
    print "sean"
    print "#{generate_secondname}"
  elsif dice > 0.80 && dice < 0.89
    print "ysabel"
    print "#{generate_secondname}"
  else dice > 0.90 && dice < 0.99
  print "patricia"
  print "#{generate_secondname}"
  end
end

file1 = File.new("randomname.txt", "a")

arr1 = []

name = generate_name(generate_secondname).to_s

file1.puts name.to_s

我尝试将结果放入数组中,然后使用:

arr1 << name
file.puts arr1

但它没有用。

我也尝试使用哈希:

file.puts "#{generate_name(generate_secondname)}"

哪个不起作用。

函数内部只是rand方法和一堆带有名称字符串的if / else语句。

2 个答案:

答案 0 :(得分:2)

Ruby使打开文件以便附加,写入并关闭它变得非常容易。这样做的惯用方法是:

File.open('randomname.txt', 'a') do |fa|
  fa.puts 'foo'
end

我们使用块形式,因为Ruby会在块存在时自动关闭文件。这使我们的代码非常干净。

就Ruby而言,为追加而打开的文件只是一系列字节。基本上当前文件位置在写入发生之前设置为文件的末尾,有效地附加。就我们的代码而言,没有其他任何东西需要。

保存上面的代码并运行两次,然后查看&#34; randomname.txt&#34;它将包含

foo
foo
  

当我尝试将结果保存到文件时,它会输入一个空行或者说“#34; true&#34;。

然后问题出现在别处,而不是在I / O部分。你没有告诉我们

中的内容
name = generate_name(generate_secondname).to_s

因此无法调试黑匣子。使用基本的调试技巧,您应该将问题分解为尽可能最小的步骤,并证明/反驳它们是否正常工作。这就是上面的代码所做的,它证明附加一个固定字符串是有效的。

第二步是介绍你应该生成输出字符串的方法。如果输出到文件的字符串错误,那么您立即知道该方法是错误的,因此在那里开始测试。或者,反转过程并编写代码以仅测试您的方法,然后在File.open块周围进行测试。无论哪种方式,将问题缩小到最小的步骤。


(代码添加到问题后添加)

返回您的代码......

else没有进行比较或代码,只有else,所以请勿使用此代码:

else dice > 0.90 && dice < 0.99

改为使用:

else

您的代码也存在一些逻辑错误。 rand返回一个Float,您的代码没有充分处理可能的值范围。考虑一下:

rand # => 0.5082475113018177

rand没有返回舍入到100的数字,所以它的精度会在你的条件中挤出漏洞:

dice = 0.091
if (dice >= 0.01) && (dice <= 0.09)
  puts "ashley"
elsif dice > 0.10 && dice < 0.19
  puts "george"
# elsif dice > 0.20 && dice < 0.29
#   puts "nick"
# elsif dice > 0.30 && dice < 0.39
#   puts "sam"
# elsif dice > 0.40 && dice < 0.49
#   puts "roland"
# elsif dice > 0.50 && dice < 0.59
#   puts "preston"
# elsif dice > 0.60 && dice < 0.69
#   puts "brandon"
# elsif dice > 0.70 && dice < 0.79
#   puts "sean"
# elsif dice > 0.80 && dice < 0.89
#   puts "ysabel"
else dice > 0.90 && dice < 0.99
  puts "patricia"
end
# >> patricia

dice大于0.09但小于0.1,因此您的行动起点很大。只要值与您想要的范围不匹配,逻辑就会落空并点击else。 (当然可能是理想的结果,但是你必须在代码中记录它,并希望有人不会在以后出现并且修复&#34;问题是因为这样做非常不直观。)

相反,你需要关闭这些漏洞。我会用以下的方式来做这件事:

dice = 0.091
name = case 
       when dice >= 0.90
         "patricia"
       when dice >= 0.80
         "ysabel"
       when dice >= 0.70
         "sean"
       when dice >= 0.60
         "brandon"
       when dice >= 0.50
         "preston"
       when dice >= 0.40
         "roland"
       when dice >= 0.30
         "sam"
       when dice >= 0.20
         "nick"
       when dice >= 0.10 
         "george"
       else 
         "ashley"
       end
puts name
# >> ashley

通过颠倒测试的顺序,我不需要设置测试的顶部边界,并且我不会遇到间隙问题。它也更容易阅读。

最后,不要这样做:

"#{generate_second_name}"

浪费CPU时间。 generate_second_name已经返回一个字符串,因此您要对字符串进行字符串化处理:

def generate_second_name()
  'foo'
end
generate_second_name.class # => String
"#{generate_second_name}".class # => String

相反,请改用裸generate_second_name

答案 1 :(得分:0)

您需要将问题分解成更小的部分。首先检查一下是否可以write to a file。确保您没有要编写的文件已经使用编辑器打开。

begin
  file = File.open("/tmp/some_file", "w")
  file.write("your text") 
rescue IOError => e
  #some error occur, dir not writable etc.
ensure
  file.close unless file == nil
end

如果正确写入“您的文字”,则将generate_name结果换成“您的文字”。接下来,您可以更改文件的打开位置。假设它仍然有效,则可以消除由权限问题引起的可能性。最后,尝试删除file.close部分,看看是否可以重现相同的问题。

编辑:

在查看您的generate_secondname方法后,我相信您可以解决问题,只需将单词print的每个实例更改为return

例如:

...
if dice > 0.01 && dice < 0.09
    return "saunders" # you must return the strings, NOT print them
elsif dice > 0.10 && dice < 0.19
...

对于generate_name,您需要在返回之前合并字符串。例如:

...
if (dice >= 0.01) && (dice <= 0.09)
  return "ashley #{generate_secondname}" # see how this is now 1 line, instead of 2
elsif dice > 0.10 && dice < 0.19
...