我是Ruby的初学者,并且在弄清楚为什么我无法修改位于块外的初始化变量时遇到了一些麻烦。例如,我想做以下(但没有for循环,因为我听说在Ruby中使用它会导致一些讨厌的错误):
sentence = "short longest"
def longest_word(sentence)
max_length = 0
for word in sentence.split(" ")
if word.length > max_length
max_length = word.length
max_word = word
end
end
return max_word
end
我尝试了什么:
def longest_word(sentence)
max_length = 0
sentence.split(" ").each do |word|
if word.length > max_length
max_length = word.length
max_word = word
end
end
return max_word
end
我知道你可以使用这样的东西:
def longest_word(sentence)
return sentence.split(" ").each.map {|word| [word.length, word]}.max[1]
end
同样想了解为什么我不能像执行for循环方法一样执行.each方法。任何帮助将不胜感激!
答案 0 :(得分:5)
首先,请注意,最简单的方法是:
sentence.split(" ").max_by(&:length)
您的方法,可以略微简化为:
sentence.split(" ").map {|word| [word.length, word]}.max[1]
也有效,但更加混乱。
Array comparison以“元素方式”的方式工作。例如,[2, "foo"] > [1, "bar"]
因为2 > 1
。这就是max
在这种情况下工作的原因:因为你实际上间接地比较了每个数组的第一个元素。
为什么我不能像执行for循环方法那样使用.each方法?
因为块中定义的变量只能在该块中访问。
这是几乎所有语言中非常常见的编程原则,称为scope of the variable。
def longest_word(sentence)
max_length = 0
sentence.split(" ").each do |word|
if word.length > max_length
max_length = word.length
max_word = word # <--- The variable is defined IN A BLOCK (scope) here
end
end
return max_word # <--- So the variable does not exist out here
end
一个简单的解决方法(但正如我上面提到的,这不是我推荐的实际解决方案!)是在块外部初始化变量:
def longest_word(sentence)
max_length = 0
max_word = nil # <--- The variable is defined OUTSIDE THE BLOCK (scope) here
sentence.split(" ").each do |word|
if word.length > max_length
max_length = word.length
max_word = word
end
end
return max_word # <--- So the variable exists here
end