On Thu, Nov 27, 2003 at 03:08:17AM +0900, Orion Hunter wrote:
> irb:1> str = "isn't stands for is not"
> irb:4> str.sub( '\'', '\\\' ) --> "isnt stands for is nott stands for is 
> not" (huh? Why this wierd double take?)

Because of the extra processing that substution strings undergo.  Within
the substitution, \& is replaced by the portion of the original string 
which matched;  \` by the portion before the match; and \' by the portion
after.  So in your case you have this:

	SEQUENCE	REPLACED BY
	\`		isn
	\&		'
	\'		t stands for is not

> irb:6> str.sub( '\'' ){ |m| m = "\\'" } --> "isn\\'t stands for is not" 
> (why did it insert TWO \s?, and not just one? I would have exected the 
> first one to "escape" the second, thus giving \' as desired)

It DIDN'T insert two backslashes; it inserted one, which shows up in
the inspection of a string as two becuase the inspection uses the
double-quote syntax.  If you print the string out with puts or otherwise
look into it, you'll see that there is only one backslash:

	irb(main):007:0> x =  str.sub( '\'' ){ |m| m = "\\'" }
	=> "isn\\'t stands for is not"
	irb(main):008:0> puts x
	isn\'t stands for is not
	=> nil
	irb(main):009:0> x[2,1]
	=> "n"
	irb(main):010:0> x[3,1]
	=> "\\"
	irb(main):011:0> x[4,1]
	=> "'"

By the way, you can simplify to just this:

	irb(main):006:0> str.sub(/'/) { '\\\'' }
	=> "isn\\'t stands for is not"

And you can also use the string form if you use the
proper number of backslashes:

	irb(main):002:0> str.sub(/'/, '\\\\\'')
	=> "isn\\'t stands for is not"

-Mark