Ruby is a language like Java, everything is reference to object. An assignment does not produce copy of the value, but the copy of the reference. So if you have an a
object, and you say b=a
then you will have a b
object reference pointing to the same place as a
.
The naive approach of a string is that if I say a='x12345y'; b=a; b.sub!('234','---');
will result in an a
which's value is 'x12345y'
and a b
which's value is 'x1---5y'
.
The Java guys invented the immutable pattern which means that after a string is created it cannot be modified. The sensation of modification comes from the construction of new strings from old ones, like s = s.concat("TEST")
where s.concat("TEST")
creates a new string which's reference may or may not be stored back at s
itself.
But Ruby has weird behavior:
original = '|123|123|123|123|' s = original s['123']='TEST' print(s,"\n") s = original s.sub!('123','TEST') print(s,"\n")will output
|TEST|123|123|123| |TEST|TEST|123|123|
You do not know enough- they say,
There are immutable objects in ruby too!. I just have to call the
freeze
method and the object will be immutable. Let's try it.
original = '|123|123|123|123|' original.freeze # <--- NEW GUY s = original s['123']='TEST' print(s,"\n") s = original s.sub!('123','TEST') print(s,"\n")will output
stringtest.rb:4:in `[]=': can't modify frozen string (TypeError) from stringtest.rb:4
That is just plain wonderful. We are still on the same place: nowhere. What would be the solution? Nothing sane is available. You have to use s = String.new(original)
instead of simple assignment. This is a terrible looking pain in the ass solution.
Who the hell knows where was my string declared at the first time? Who knows what will be broken if I change a string I got from somewhere? Who will find the real problem for an error message like File not found: 'TEST'
?
Oh my god
ReplyDeletesynapse