Project

General

Profile

This project is closed and read-only.

Actions

Bug #3147

closed

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

Bug #3147: gsub evaluates the passed in replacement string making results unpredictable when replacement string is dynamically generated

Added by wwalker (Wayne Walker) over 16 years ago. Updated over 15 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

Updated by wwalker (Wayne Walker) over 16 years ago Actions #1

=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

Updated by shyouhei (Shyouhei Urabe) over 16 years ago Actions #2

  • 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

Updated by wwalker (Wayne Walker) over 16 years ago Actions #3

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

=end

Updated by murphy (Kornelius Kalnbach) over 16 years ago Actions #4

=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: PDF Atom