为什么我的重构红宝石不使用注入工作?

时间:2010-09-27 05:14:35

标签: ruby refactoring inject

我尝试进行一些重构,将每个块转换为注入,但它不起作用,我不明白为什么。

以下是重构前的代码:

class String
  # Build the word profile for the given word. The word profile is an array of
  # 26 integers -- each integer is a count of the number of times each letter
  # appears in the word. 
  #
  def profile
    profile = Array.new(26) { 0 }
    self.downcase.split(//).each do |letter|
      # only process letters a-z
      profile[letter.ord - 'a'.ord] += 1 unless letter.ord > 'z'.ord
    end
    profile
  end
end

这是我的重构不起作用:

class String
  # Build the word profile for the given word. The word profile is an array of
  # 26 integers -- each integer is a count of the number of times each letter
  # appears in the word. 
  #
  def profile
    self.downcase.split(//).inject(Array.new(26) {0}) do |profile, letter|
      # only process letters a-z
      profile[letter.ord - 'a'.ord] += 1 unless letter.ord > 'z'.ord 
    end
  end
end

当我尝试执行重构方法时,我正在

`block in profile': undefined method `[]=' for 1:Fixnum (NoMethodError)

如果我理解正确,它不像我的重构版本中的配置文件对象上的数组引用运算符,这意味着传递给inject的初始化器不起作用。这种理解是否正确?如果是这样,为什么不呢?

谢谢!

1 个答案:

答案 0 :(得分:3)

[]=方法返回指定的值,因此下一次迭代中profile的值将为1(因为它是最后一次迭代的值)。为了获得您想要的行为,您必须这样做:

self.downcase.split(//).inject(Array.new(26) {0}) do |profile, letter|
  # only process letters a-z
  profile[letter.ord - 'a'.ord] += 1 unless letter.ord > 'z'.ord 
  profile
end

self.downcase.split(//).inject(Array.new(26) {0}) do |profile, letter|
  # only process letters a-z
  profile.tap { profile[letter.ord - 'a'.ord] += 1 unless letter.ord > 'z'.ord }
end