Project

General

Profile

Actions

Bug #3147

closed

gsub evaluates the passed in replacement string making results unpredictable when replacement string is dynamically generated

Added by wwalker (Wayne Walker) about 14 years ago. Updated almost 13 years ago.

Status:
Rejected
Assignee:
-
ruby -v:
ruby 1.8.6 (2009-08-04 patchlevel 383) [i386-linux]
[ruby-core:29514]

Description

=begin
after the interpreter evaluates the replacement string (if it's a literal in "" or ''), gsub further evaluates it during execution changing the effective replacement string.

irb(main):016:0> a = 'Y'
=> "Y"
irb(main):017:0> b = 'Z\1'
=> "Z\1"
irb(main):018:0> c = '\\1'
=> "\\1"
irb(main):019:0> a.gsub(/(Y)/, b)
=> "ZY"
irb(main):020:0> a.gsub(/(Y)/, c)
=> "\1"

The last result is expected to be "\Y"
=end

Actions #1

Updated by wwalker (Wayne Walker) about 14 years ago

=begin
This bug also exists in :

jruby 1.3.1 (ruby 1.8.6p287) (2009-06-15 2fd6c3d)
ruby 1.9.1p376 (2009-12-07 revision 26041) [i686-linux]
=end

Actions #2

Updated by shyouhei (Shyouhei Urabe) about 14 years ago

  • Status changed from Open to Rejected

=begin
"\\1", backslash-backslash-one, is a backslash-escaped backslash plus literal 1.
If what you want to get "\Y" you need another backslash to escape 1 i.e. "\\\1",
backslash-backslash backslash-one.
=end

Actions #3

Updated by wwalker (Wayne Walker) about 14 years ago

=begin
This at least needs to be documented clearly in gsub. Strings are normally only evaluated once, not twice.

=end

Actions #4

Updated by murphy (Kornelius Kalnbach) about 14 years ago

=begin
I use the pattern str.gsub(pattern) { replacement } when I'm not sure
about the replacement. In this case:

'Y'.gsub(/(Y)/) { '\' + $1 }

This specific example could also be written as:

'Y'.gsub(/(?=Y)/, '\')

Both avoid the backslash issue.

Escaping rules in replacement strings are indeed confusing. If you want
a single backslash in the output, you need four of them in the literal.

Adding Wayne's examples to the documentation would certainly help to
understand this.

[murphy]

=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0