Search/Replace weirdness
Why does开发者_运维知识库 this code only modify the last file in the array? The files are both readable and writeable by my user.
%w(views/layout.rhtml views/admin/layout.rhtml).each do |file|
text = File.read(file)
File.open(file, 'w+') do |f|
f << text.gsub(/\?v=(\d+)/, "?v=#{$1.to_i + 1}")
end
end
Your problem is that you're not using the block form of gsub
so $1
and similar globals are not set as you think they are. From the fine manual:
If replacement is a String it will be substituted for the matched text. It may contain back-references to the pattern‘s capture groups of the form
\\d
, where d is a group number, or\\k<n>
, where n is a group name. If it is a double-quoted string, both back-references must be preceded by an additional backslash. However, within replacement the special match variables, such as &$, will not refer to the current match.
And:
In the block form, the current match string is passed in as a parameter, and variables such as
$1
,$2
,$&
, and$’
will be set appropriately. The value returned by the block will be substituted for the match on each call.
Bolding mine. Also, I left out the backtick global:
$`
To avoid problems with the Markdown (if anyone knows how to get a backtick in an inlined code block I'd appreciate a pointer).
If you do this instead:
%w(views/layout.rhtml views/admin/layout.rhtml).each do |file|
text = File.read(file)
File.open(file, 'w+') do |f|
f << text.gsub(/\?v=(\d+)/) { "?v=#{$1.to_i + 1}" }
end
end
I think you'll get the results that you're looking for.
精彩评论