У вас уже есть решение со второй попытки, вы просто запутались, потому что строка отображается в экранированном виде в интерактивном интерпретаторе. Но на самом деле есть только один обратный слеш, а не два. Попробуйте распечатать его, используя Put, и вы увидите, что на самом деле есть только одна обратная косая черта:
> "foo ( bar ) foo".gsub("(", "\\(")
=> "foo \\( bar ) foo"
> puts "foo ( bar ) foo".gsub("(", "\\(")
foo \( bar ) foo
Если вам нужна дополнительная убедительность, попробуйте взять длину строки:
> "foo ( bar ) foo".length
=> 15
> "foo ( bar ) foo".gsub("(", "\\(").length
=> 16
Если бы он добавил две обратные косые черты, он напечатал бы 17, а не 16.