как передать строки в функции не по ссылке (Ruby) - PullRequest
1 голос
/ 10 мая 2011

Проверьте следующий код

def wipe_mutterings_from( sentence )
   while sentence.include? '('
     open = sentence.index( '(' )
     close = sentence.index( ')', open )
     sentence[open..close] = '' if close
   end
end

foo='abbba (jjjj) kkkkkk'
wipe_mutterings_from( foo )
p foo

В моем понимании я передал строку с помощью ref функции (очень похоже на то, что делается на языках более низкого уровня, таких как c / cpp).
Возможно липередать строку только по значению (как в PHP)?
Я полностью осознаю, что могу дублировать строку внутри функции и работать только с копией.

Ответы [ 4 ]

3 голосов
/ 10 мая 2011

Нет, все передается по ссылке в Ruby, и строки являются изменяемыми. Как вы уже упоминали, обычным делом является dup строка в методе.

Однако гораздо более простой способ - просто не делать sentence[open..close], а вместо этого что-то вроде sentence[0...open] + sentence[(close + 1)..-1], которое создает новую строку для каждой итерации. Таким образом, вам не придется беспокоиться о мутировании строки. С другой стороны, это решение может создать гораздо больше строковых объектов, что снижает производительность, поскольку сборщик мусора должен выполнять гораздо больше работы, но это актуально только в том случае, если вы делаете это десятки тысяч раз.

1 голос
/ 10 мая 2011

Или вы можете попробовать более "рубиновый" способ (исключая циклы while и вычисления индекса):

foo = 'abbba (jjjj) kkkkkk'
p foo.sub(/\(.*\) /, '')
0 голосов
/ 10 мая 2011

Я не вижу причин, почему бы вам не создать новую строку в функции и не вернуть ее. Это читается намного лучше и будет меньше сюрпризов:

foo='abbba (jjjj) kkkkkk'
new_foo = wipe_mutterings_from( foo )
p new_foo

или даже

foo='abbba (jjjj) kkkkkk'
foo = wipe_mutterings_from( foo )
p foo

Я бы предпочел последнее.

0 голосов
/ 10 мая 2011

Вы можете попытаться отправить только копию этой строки

foo='abbba (jjjj) kkkkkk'
wipe_mutterings_from( foo.clone )
p foo
...