Ruby:隐式 return 值如何在块中工作?

Ruby: How does implicit return value work in blocks?

编辑: 我原来的问题原来与我的实际问题无关,但在这个过程中我学到了一些东西,我决定改写我最初的陈述。

我想用字符串中一对括号内的 _ 替换每个 space </code>。这是我的示例输入:</p> <pre><code>This is my string (nice, isn't it?). It can have various types [of input].

期望的输出:

This is my string (nice,_isn't_it?). It can have various types [of_input].

我有以下代码:

my_string = my_string.gsub(/\([^\(\)]+\)|\[[^\[\]]+\]/) { |bracketed|
    bracketed.gsub(/ /, '_')
}

为什么bracketed.gsub(/ /, '_')等于bracketed = bracketed.gsub(/ /, '_')?这与 gsub! 有何不同?我不完全理解 Ruby 假设 return 背后的逻辑。

Why does bracketed.gsub(/ /, '_') equal to bracketed = bracketed.gsub(/ /, '_')? How is that different from gsub!?

  • gsub return 一个 新的 字符串。
  • gsub! 更改 现有 字符串。

所以 bracketed = bracketed.gsub(/ /, '_')bracketed.gsub!(/ /, '_') 几乎是等价的。

(只有 次要 行为差异在于,如果没有模式匹配,gsub! 将 return nil。但无论哪种方式,您将以相同的方式改变原始 bracketed 变量。)

但是,你问错了问题...让我们再看看你的原始代码,它可以写成:

my_string.gsub!(/\([^)]+\)|\[[^\]]+\]/) do |bracketed|
  bracketed.gsub(/ /, '_')
end

来自 the documentation for String#gsub:

In the block form, the current match string is passed in as a parameter [...] The value returned by the block will be substituted for the match on each call.

在 ruby 中,method/block 中的最终评估行是其 隐式 return 值。您在这里所做的只是将一个值传回原来的 gsub 方法; 没关系你是否mutate/reassignbracketed变量。

也许这个例子会让事情变得更清楚:

"hello (world)".gsub!(/\([^)]+\)|\[[^\]]+\]/) do |bracketed|
  bracketed = "something different"
  "TEST!!!"
end

  # => "hello (TEST!!!)"