Строки изменяются в Ruby?
Являются ли Strings mutable в Ruby? Согласно документации ,
str = "hello"
str = str + " world"
создает новый строковый объект со значением "hello world"
, но когда мы делаем
str = "hello"
str << " world"
Не упоминается, что он создает новый объект, поэтому он мутирует объект str
, который теперь будет иметь значение "hello world"
?
Ответы
Ответ 1
Да, <<
мутирует один и тот же объект, а +
создает новый. Демонстрация:
irb(main):011:0> str = "hello"
=> "hello"
irb(main):012:0> str.object_id
=> 22269036
irb(main):013:0> str << " world"
=> "hello world"
irb(main):014:0> str.object_id
=> 22269036
irb(main):015:0> str = str + " world"
=> "hello world world"
irb(main):016:0> str.object_id
=> 21462360
irb(main):017:0>
Ответ 2
Просто для дополнения, один из признаков этой изменчивости выглядит ниже:
ruby-1.9.2-p0 :001 > str = "foo"
=> "foo"
ruby-1.9.2-p0 :002 > ref = str
=> "foo"
ruby-1.9.2-p0 :003 > str = str + "bar"
=> "foobar"
ruby-1.9.2-p0 :004 > str
=> "foobar"
ruby-1.9.2-p0 :005 > ref
=> "foo"
и
ruby-1.9.2-p0 :001 > str = "foo"
=> "foo"
ruby-1.9.2-p0 :002 > ref = str
=> "foo"
ruby-1.9.2-p0 :003 > str << "bar"
=> "foobar"
ruby-1.9.2-p0 :004 > str
=> "foobar"
ruby-1.9.2-p0 :005 > ref
=> "foobar"
Итак, вы должны разумно выбирать методы, которые вы используете со строками, чтобы избежать неожиданного поведения.
Кроме того, если вы хотите что-то неизменное и уникальное во всем своем приложении, вы должны пойти с символами:
ruby-1.9.2-p0 :001 > "foo" == "foo"
=> true
ruby-1.9.2-p0 :002 > "foo".object_id == "foo".object_id
=> false
ruby-1.9.2-p0 :003 > :foo == :foo
=> true
ruby-1.9.2-p0 :004 > :foo.object_id == :foo.object_id
=> true