信岡です。
どうすればよいかは okkez さんが示されていますが、なぜそうなるのか
簡単に説明を。
String#gsub の第 2 引数では、「\&」 でマッチした文字列を表したり
「\1」 で最初のキャプチャ文字列を表したりできるわけで、バックスラッシュに
特別な意味があります。 そのため、単なるバックスラッシュを表したい場合には
バックスラッシュを 2 つ連続させる必要があります。
(ただし、バックスラッシュと後ろの文字の組み合わせが特に意味をもたない場合は、
単一のバックスラッシュでもバックスラッシュとして認識されるみたいです。)
さらに、単一引用符 (または二重引用符) でくくられた文字列リテラルの中において、
バックスラッシュはエスケープに使われるメタ文字であるため、
バックスラッシュという文字を表すためにはバックスラッシュを 2 つ連続させる必要があります。
よって、String#gsub メソッドの第 2 引数に渡す文字列の中で、単なるバックスラッシュに
変換される文字を表すためには、バックスラッシュを 4 つ重ねて記す必要があります。
'a_b$c'.gsub( /[_$]/, '\\\\' )
この挙動は扱いづらいですので、gsub を使う際にはブロックを用いた方が
扱いやすいと思います。
'a_b$c'.gsub( /[_$]/ ){ '\\' }
--
信岡 ゆう (NOBUOKA Yu)