覆盖默认范围输出

时间:2011-03-04 07:00:52

标签: ruby iterator range

现在,下面的代码生成它下面的输出,但是对于我给定的情况,如何将默认输出覆盖为更合理的输出。我知道我可以在范围之后附加字符串"Hz",但我希望将其合并到一个模块中,该模块可以在需要时包含在Range类中或与refinements一起使用。

代码:

("20Hz"..."40Hz").each { |hz| p hz }     

输出:

"20Hz"
"20Ia"
"20Ib"
...etc

通缉输出:

"20Hz"
"21Hz"
"22Hz"
...etc

3 个答案:

答案 0 :(得分:1)

我觉得很简单。

  ("20"..."40").each { |hz| p hz + 'Hz'}

答案 1 :(得分:1)

我建议为此创建自己的函数或类,而不是改变Ruby范围的行为方式。可能有很多其他代码依赖于以特定方式工作的范围,并且更改范围定义将导致代码中断。你可能想要瞄准这样的事情:

HzRange.new("20Hz", "40Hz").each{ |hz| p hz }

创建HzRange类取决于您,但您可能应该委托给Array或Range对象,以便继承一些默认行为,如Enumerable。

答案 2 :(得分:1)

这绝对是一个坏主意,但仅仅是为了试验:

class String
  alias_method :succ_orig, :succ

  def succ
    self.gsub(/\d+/, &:succ_orig)
  end
end

p ("20Hz".."40Hz").to_a
#=> ["20Hz", "21Hz", "22Hz", "23Hz", "24Hz", "25Hz", "26Hz", "27Hz", "28Hz", "29Hz", "30Hz", "31Hz", "32Hz", "33Hz", "34Hz", "35Hz", "36Hz", "37Hz", "38Hz", "39Hz", "40Hz"]

正如您所看到的,不是Range类应该更改,而是String#succ方法。

但在实际项目中,您最好为Hertz字符串创建一个类并适当地定义其succ方法。