为什么这个Ruby代码使用char.upcase!失败,但char = char.upcase有效吗?

时间:2014-01-02 01:18:04

标签: ruby string uppercase lowercase

我正在解决一个编码问题,为每个单词做一个有趣的案例,“LiKe ThIs”。这是我的单线解决方案。我知道这有点hacky,但是很好。

string.split(" ").map{|word| word.split("").map.with_index{|char,i|
  i.even? ? char.upcase! : char.downcase! }.join("")}.join(" ")

这为输入HLO TEE TS输出hello there test,使其看起来只有偶数情况才会被触发。但是在那里抛出一个打印声明,我可以看到是的,它正在通过每个索引。

在我的沮丧中,我把它改为:

 string.split(" ").map{|word| word.split("").map.with_index{|char,i|
   i.even? ? char = char.upcase : char = char.downcase }.join("")}.join(" ")

我觉得应该是相同的 - 更改char.upcase! to char = char.upcase ...而且神奇地说,这很有效。

这里发生了什么?

2 个答案:

答案 0 :(得分:2)

这是由于upcase!downcase!的定义。这是upcase!

  

提升str的内容,如果没有进行任何更改则返回nil。注意:案例替换仅在ASCII区域有效。

请注意,如果未进行任何更改,则会返回nil。在这种情况下,如果您正在迭代的字符已经在正确的情况下,它将返回nil并有效地从字符串中删除字符作为map函数的一部分。

在您的具体示例中,您会注意到其他每个字符都被删除,因为它已经是小写字母而downcase!正在返回nil

答案 1 :(得分:-1)

考虑更清楚地编写代码:

string = 'foo bar'
string.split.map{ |w|
  w.split('').map.with_index{ |char, i|
    i.even? ? char.upcase : char.downcase 
  }.join
}.join(' ')
# => "FoO BaR"

或者,即便如此:

string.split.map{ |w|

  w.split('').map.with_index{ |char, i|
    if i.even? 
      char.upcase 
    else
      char.downcase 
    end
  }.join

}.join(' ')
# => "FoO BaR"

应谨慎使用三元陈述。在像C和Perl这样的语言中,你会发现它们经常被使用,但在Ruby中,它们的使用经常被劝阻,因为它们可能更难以阅读/理解。如果/何时使用它们,请记住维护和可读性。