使用Ruby来解决测验

时间:2015-07-13 18:49:05

标签: ruby

所以我在一个网站上发现了这个测验,我很高兴用我新获得的Ruby技能解决这个问题(CodeAcademy,尚未完成)。

我想要做的是创建一个包含100个条目的数组,所有条目都设置为“打开”。然后,我计划创建一个包含for循环的方法,该循环遍历数组的每个第n个条目,并根据之前的内容将其更改为“open”或“closed”。在for循环中,n应该从1增加到100。

到目前为止我所拥有的是:

change_state = Proc.new { |element| element == "open" ? element = "closed" : element = "open" }

def janitor(array,n)
    for i in 1..n
        array.each { |element| if array.index(element) % i == 0 then element.change_state end }
    end
end

lockers = [*1..100]

lockers = lockers.map{ |element| element = "closed" }

result = janitor(lockers,100)

尝试执行时收到错误消息:

undefined method `change_state' for "closed":String (NoMethodError)

有人知道这里有什么问题吗?我觉得我在当前数组元素上错误地调用了“change_state”过程。

如果你知道测验,请不要剧透!

1 个答案:

答案 0 :(得分:3)

当您实现change_state时,它不是任何类的方法,并且绝对不会附加到数组的任何单个元素,尽管您使用相同的变量名element。因此,您无法将其称为element.change_state

相反,它是一个指向Proc对象的变量。

要调用Proc对象中的代码,您可以使用call方法和proc_obj.call( params )之类的语法 - 在您的情况下change_state.call( element )

如果您刚刚接受该更改,则错误消息将更改为:

NameError: undefined local variable or method `change_state' for main:Object

那是因为change_state变量不在方法范围内,以便被调用。有很多方法可以使它可用。一种选择是将其作为参数传递,因此您对janitor的定义变为

 def janitor(array,n,state_proc)

(在您的例程中使用变量名state_proc而不是change_state - 我建议您更改名称以避免让自己感到困惑)

然后您可以这样称呼它:

result = janitor(lockers,100,change_state)

尽管您的示例并不真正需要这种结构,但这是Ruby代码可以提供通用“外部”功能的一种方式 - 比如说,通过数组的元素 - 并让该代码的用户提供一个小的内部自定义部分。实现与示例相同结果的更常见方法是使用Ruby块和yield方法,但Proc也有其用途,因为您可以将它们视为数据和代码 - 所以你可以传递它们,将它们放入哈希或数组中以决定调用哪一个等。

您的代码中可能还有其他问题需要解决,但这是问题中错误消息的原因。