红宝石koan三明治行数

时间:2014-01-25 00:43:23

标签: ruby block

我正在处理Ruby Koans示例中的about_sandwich_code示例,在此处完成代码链接about_sandwich_code.rb以供参考。以下是相关参考代码,以便于参考。

  def count_lines(file_name)
    file = open(file_name)
    count = 0
    while file.gets
      count += 1
    end
    count
  ensure
    file.close if file
  end

  def test_counting_lines
    assert_equal 4, count_lines("example_file.txt")
  end

  # ------------------------------------------------------------------

  def find_line(file_name)
    file = open(file_name)
    while line = file.gets
      return line if line.match(/e/)
    end
  ensure
    file.close if file
  end

  def test_finding_lines
    assert_equal "test\n", find_line("example_file.txt")
  end

  def file_sandwich(file_name)
    file = open(file_name)
    yield(file)
  ensure
    file.close if file
  end

在我尝试编写find_line2方法时,我尝试了以下编译的代码。

    def find_line2(file_name)
     file_sandwich(file_name) do |file|
      while file.gets
        return file.gets if file.gets.match(/e/)
      end
     end
    end

  def test_finding_lines2
    assert_equal "test\n", find_line2("example_file.txt")
  end

供参考,example_file.txt

但是,koans在终端窗口中返回以下内容:Expected "test\n" to equal nil

这提高了我的意识,因为倒数第二个koan代码/测试类似的发现线功能前三明治代码解决了这个问题。

  def test_finding_lines
    assert_equal "test\n", find_line("example_file.txt")
  end

当我尝试不同的选项时,我意识到以下find_line2实现

def find_line2(file_name)
file_sandwich(file_name) do |file|
  while line = file.gets
    return line if line.match(/e/)
  end
end

使用

运行时
  def test_finding_lines2
    assert_equal "test\n", find_line2("example_file.txt")
  end

解决了公案而不是告诉我测试应该等于前面的截图显示的nil。所以这相当于我在这一刻所理解的是,我的第一个实现以某种方式改变了koan程序所期望的检查,这让我感到困惑。我认为这意味着我的尝试不知何故打破了公案,但我不确定为什么。实际上,在运行file_sandwich和我find_line2的第一次实施后,我看到调用find_line2("example_file.txt")要返回nil,因此出于某种原因,file.gets的行为与使用{line不同在line = file.gets声明中的while之后{1}}。

有人可以解释为什么我的第一次实施和答案不相等吗?我相信答案在于对块的更清楚的理解?

1 个答案:

答案 0 :(得分:0)

def find_line2(file_name)

 file_sandwich(file_name) do |file|

  while file.gets #gets the next line in the file

    if file.gets.match(/e/) #gets the next line and checks for a match
      return file.gets #gets the next line and returns it. 
    end #restructured for clarity 
  end
 end
end

因此,使用示例文件This\nis\na\ntest,代码获取This\n,获取is\n并检查(fail)。在下一次迭代中,您的代码获取a\n,获取test\n并检查(true),然后获取下一行(nil)并返回它。