has_key与.downcase结合使用不正常

时间:2014-11-16 18:37:46

标签: ruby

如果我从这个

中更改代码,我会对这种情况下的downcase行为感到困惑
module FunWithStrings
def count_words
    hash = Hash.new
    self.split(" ").each do |i| 
      i.downcase!
      if !hash.has_key?(i)
        hash[i] = 1 
      else
        hash[i] += 1
      end 
    end 
  hash
  end 
end

class String
  include FunWithStrings
end


p "test hello test Test wow".count_words
正确计数

输出正确 {" test" => 3,"你好" => 1,"哇" => 1} 如果我尝试最小化代码并将其切换到i.dow​​ncase!在has_key函数调用它打印出错误的值。不知道为什么。

module FunWithStrings

  def count_words
    hash = Hash.new
    self.split(" ").each do |i| 
      if !hash.has_key?(i.downcase!)
        hash[i] = 1 
      else
        hash[i] += 1
      end 
    end 
  hash
  end 
end

class String
  include FunWithStrings
end


p "test hello test Test wow".count_words

{" test" => 2,"你好" => 1,"哇" => 1}

1 个答案:

答案 0 :(得分:4)

您遇到的问题是因为您正在呼叫String#downcase!而不是String#downcase。如果你运行IRB并测试它,你会看到:

> "TeSt".downcase!
=> "test"
> "test".downcase!
=> nil
> "TeSt".downcase
=> "test"
> "test".downcase
=> "test"

这里发生的是,如果字符串已经是小写,那么String#downcase!将返回nil;但是,即使初始字符串已经是小写,替代String#downcase也将始终返回有效的小写字符串。同样重要的是要注意String#downcase!修改变量引用的字符串对象,这可能是也可能不是期望的结果。

> s = "TeSt"
=> "TeSt"
> s.downcase!
=> "test"
> s
=> "test"

这通常不是您想要做的,而是要调用未标记的downcase,它返回一个表示字符串小写版本的新String对象。