Ruby 为什么将字符串元素的第一个字母大写会改变数组?

Ruby 为什么将字符串元素的第一个字母大写会改变数组?,ruby,Ruby,以下代码旨在将字符串中每个单词的第一个字母大写,并且可以正常工作: def capitalize_words(string) words = string.split(" ") idx = 0 while idx < words.length word = words[idx] word[0] = word[0].upcase idx += 1 end return words.join(" ") end capitalize_words("t

以下代码旨在将字符串中每个单词的第一个字母大写,并且可以正常工作:

def capitalize_words(string)
  words = string.split(" ")
  idx = 0
  while idx < words.length
    word = words[idx]
    word[0] = word[0].upcase
    idx += 1
  end
  return words.join(" ")
end

capitalize_words("this is a sentence") # => "This Is A Sentence"
capitalize_words("mike bloomfield") # => "Mike Bloomfield"
然后我会修改
单词的元素。但是,即使没有这一行代码也可以工作

然而,在while循环中,我并没有用它来资本化 每个单词的第一个字母我实际上设置了 “words”数组表示任何新内容

实际上,就在这里:

word = words[idx]
word[0] = word[0].upcase # This changes words[idx][0]!
该方法的作用是:返回给定字符串的
upcase
。例如:

'example'.upcase
# => "EXAMPLE" 
'example'[0].upcase
# => "E" 
您在中使用的方法
String#[]=

word[0] = ...

不是变量赋值。它在给定索引处更改接收方字符串的内容,保留字符串作为对象的标识。由于
word
不是副本,而是取自
words
的原始字符串,因此,您正在修改
words

您正在做大量不必做的工作:

def capitalize_words(string)
  string.split.map{ |w|
    [w[0].upcase, w[1..-1]].join # => "Foo", "Bar"
  }.join(' ')
end

capitalize_words('foo bar')
# => "Foo Bar"
细分:

'foo'[0] # => "f"
'foo'[0].upcase # => "F"
'foo'[1..-1] # => "oo"

['F', 'oo'].join # => "Foo"

FWIW,有一种方法。谢谢-我知道大写方法,但我想了解为什么这种将字符串中的每个单词大写的特殊手动方法有效。这与Brito的答案一起非常有用。你提供了一个更彻底的解释,但是他的第一个代码块直接回应了我的部分问题,这让我很容易理解到底发生了什么。所以。。。Ruby通过引用将
words[idx]
传递给
word
,而不是创建单独的值?有趣的。。。在某个项目上,它对我的影响正好相反。@c650嗯,有点像。严格地说,Ruby是一种传递值语言,但所有值都是引用(请注意,
[]
是一个函数;编写
'abc'[1]
只是编写
'abc.[](1)
的一种更简单的方法)。你应该检查一下这个问题。
'foo'[0] # => "f"
'foo'[0].upcase # => "F"
'foo'[1..-1] # => "oo"

['F', 'oo'].join # => "Foo"