Ruby:Proc来反转一个字符串

时间:2014-02-09 06:18:03

标签: ruby rspec proc

我正在为一个红宝石课程做一些家庭作业问题而且我的答案有些麻烦。基本上我需要构建一个能满足这些条件的程序:

describe "reverser" do
 it "reverses the string returned by the default block" do
  result = reverser do
    "hello"
  end
  result.should == "olleh"
 end

 it "reverses each word in the string returned by the default block" do
  result = reverser do
    "hello dolly"
  end
  result.should == "olleh yllod"
 end
end

我困惑了一些我认为应该满足这些条件的代码:

reverser = Proc.new do |string|

 words = string.split(/\b/)

 answer = ''

 i = 0
 while i < words.count
     answer = answer + words[i].reverse
     i += 1
 end
 answer
end


def reverser
 yield

end

然而,当我运行耙子时,我的错误告诉我,我已经失败了第一个条件。

expected: "olleh"
got: "hello"

有什么我想念的吗?我是否对procs没有正确的理解?

这个问题已经由一个名为pete的成员以某种形式提出,并且被另一个名为mind.blank的用户很好地回答。这是来源:

Beginner RSpec: Need help writing Ruby code to pass RSpec tests (Silly Blocks exercise)

mind.blank的代码很简单并且工作正常,但我不想复制它而不理解为什么我的工作不起作用。提前感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

所以 - 你所得到的是一个名为“反向器”的局部变量和一个名为“反向器”的方法(它将“反映”局部反转器)

您的代码永远不会执行。

所以 - 你想要做的是......获取收益率的结果并对其进行相反的操作。 (暂且不谈这个要求有多奇怪。)

def reverser
  string = yield
  # ... all of your reverser code ...
end

现在回转 - 这是使用一个块的奇怪方式。一个块用于将附加执行传递给方法,而不是将参数传递给它。所以,如果你想说,对于反向器中的每个字符执行回调(反过来?),这将是正确使用yield。

此外,Ruby已经有一个String#reverse方法 - 所以最简单的方法就是让你的测试通过就好了。

def reverser
  (yield).split(/\b/).map(&:reverse).join
end

答案 1 :(得分:1)

如果您说reverser(或reverser.call('abc')reverser['abc']),那么您的reverser.('abc') proc会有效,那么您将获得预期的'cba'

问题是您的测试没有使用reverser proc,而是使用您的reverser方法。这是使用块调用reverser方法:

result = reverser do
  "hello"
end

但是reverser方法没有做任何有趣的事情,只是屈服于块:

def reverser
  yield
end

所以result最终成为了区块的值,而'hello'就是{。}}。

测试proc:

it "reverses the string returned by the default block" do
  result = reverser['hello']
  result.should == "olleh"
end

或将proc的内容移动到reverser方法并测试:

def reverser
  string = yield
  words  = string.split(/\b/)
  answer = ''

  i = 0
  while i < words.count
    answer = answer + words[i].reverse
    i += 1
  end
  answer
end

有更好的方法来编写此代码(例如words.map(&:reverse).join而不是while外观),但您的反转逻辑有效,您只需要确保调用正确的版本。

答案 2 :(得分:0)

此代码将作为块

反转给予方法的字符串
def reverser
    # yield is the string given in the block
    words = yield.split(' ')
    final = []
    words.each do |word|
        final.push(word.reverse)
    end
    final.join(' ')
end