Ruby: when altering string's content using []= and out of the range
I'm a newbie at Ruby, and I'm reading the "Ruby Programming Language", when encountered section "3.2.4 Accessing Characters and Substrings", there is an example illustrate using []=
to alter the string content on Page 56 and 57:
s = 'hello'; # Ruby 1.9
....
....
s[s.length] = ?! # ERROR! Can't assign beyond the end of the string
Yes, it's true, you cannot assign beyond the end of the string.
But, when I played with it on the IRB, I got a different result:irb(main):016:0> s[s.length] = ?!
=> "!"
irb(main):017:0> s
=> "hello!开发者_高级运维"
Ruby 1.9.2p180 (2011-02-18 revision 30909) on Mac OS X 10.6.8
This book is from 2008, and the example was using Ruby 1.8, in 1.9.2 it works perfectly:
# Ruby 1.8.7-p352
s = 'hello'
s[s.length] = ?!
puts s
# => IndexError: index 5 out of string
# method []= in ruby.rb at line 3
# at top level in ruby.rb at line 3
# Ruby 1.9.2-p290
s = 'hello'
s[s.length] = ?!
puts s
# => hello!
Nice pickup it does look like a Ruby 1.8 vs 1.9 thing. It looks like in 1.9 the String []=
is treated in a similar way as the String insert
method.
You can use the insert method to insert a string before a particular character in another string. So let's take our string "hello" as an example:
ruby-1.9.2-p180 :238 > s = "hello"
=> "hello"
ruby-1.9.2-p180 :239 > s.length
=> 5
ruby-1.9.2-p180 :240 > s.insert(s.length, " world")
=> "hello world"
But now lets try to use insert to insert into s.length + 1
:
ruby-1.9.2-p180 :242 > s = "hello"
=> "hello"
ruby-1.9.2-p180 :243 > s.insert(s.length + 1, " world")
IndexError: index 6 out of string
from (irb):243:in `insert'
We get the same behaviour if we use the []=
method:
ruby-1.9.2-p180 :244 > s = "hello"
=> "hello"
ruby-1.9.2-p180 :245 > s[s.length] = " world"
=> " world"
ruby-1.9.2-p180 :246 > s
=> "hello world"
ruby-1.9.2-p180 :247 > s = "hello"
=> "hello"
ruby-1.9.2-p180 :248 > s[s.length + 1] = " world"
IndexError: index 6 out of string
from (irb):248:in `[]='
So, Ruby 1.9 is clever enough to recognise when you're trying to assign to an index that is just past the end of the string and automagically treats that as an insertion/concatenation. Whether or not this behaviour is desirable probably depends on personal preference, it is certainly good to be aware that it is the behaviour you can expect.
精彩评论