Каков канонический способ обрезки строки в Ruby без создания новой строки?
Это то, что у меня есть сейчас - что выглядит слишком многословным для работы, которую он делает.
@title = tokens[Title].strip! || tokens[Title] if !tokens[Title].nil?
предположим, что токены-это массив, полученный путем разделения строки CSV. теперь функции, такие как strip! чомп! и. все вернет nil, если строка не была изменена
"abc".strip! # => nil
" abc ".strip! # => "abc"
что Рубин так сказать обрезать его, если он содержит лишние пробелы без создания копий?
становится уродливее, если я хочу сделать tokens[Title].chomp!.strip!
9 ответов
Я думаю, что вы хотите это:
@title = tokens[Title]
@title.strip!
на #strip!
метод возвращает nil
если он ничего не раздевал, и сама переменная, если она была раздета.
согласно стандартам Ruby, метод с суффиксом восклицательного знака изменяет переменную на месте.
надеюсь, что это помогает.
обновление: это вывод из irb
продемонстрировать:
>> @title = "abc"
=> "abc"
>> @title.strip!
=> nil
>> @title
=> "abc"
>> @title = " abc "
=> " abc "
>> @title.strip!
=> "abc"
>> @title
=> "abc"
кстати, теперь ruby уже поддерживает только полосу без "!".
сравниваем:
p "abc".strip! == " abc ".strip! # false, because "abc".strip! will return nil
p "abc".strip == " abc ".strip # true
также невозможно strip
без дубликатов. См. источники в строке.с:
static VALUE
rb_str_strip(VALUE str)
{
str = rb_str_dup(str);
rb_str_strip_bang(str);
return str;
}
Рубин 1.9.3p0 (2011-10-30) [i386-mingw32]
обновление 1: Как я вижу сейчас-он был создан в 1999 году (см. rev #372 в SVN):
обновление 2:
strip!
не будет создавать дубликаты - как в 1.9.x, 2.X и багажник версии.
нет необходимости как полосы, так и chomp, поскольку полоса также удалит возврат задней каретки - если вы не изменили разделитель записей по умолчанию, и это то, что вы жуете.
ответ Олли уже имеет канонический способ сделать это в Ruby, хотя, если вы обнаружите, что делаете это много, вы всегда можете определить метод для него:
def strip_or_self!(str)
str.strip! || str
end
даем:
@title = strip_or_self!(tokens[Title]) if tokens[Title]
также имейте в виду, что оператор if предотвратит @title
от назначается, если токен равен нулю, что приведет к сохранению его предыдущего значения. Если вы хотите или не возражаете @title
всегда назначается вы можете переместить проверку в метод и дополнительно уменьшить дублирование:
def strip_or_self!(str)
str.strip! || str if str
end
в качестве альтернативы, если вы чувствуете себя предприимчивыми, вы можете определить метод на себе строку:
class String
def strip_or_self!
strip! || self
end
end
один из:
@title = tokens[Title].strip_or_self! if tokens[Title]
@title = tokens[Title] && tokens[Title].strip_or_self!
Если вы используете Ruby on Rails, есть хлюпать
> @title = " abc "
=> " abc "
> @title.squish
=> "abc"
> @title
=> " abc "
> @title.squish!
=> "abc"
> @title
=> "abc"
Если вы используете только Ruby, вы хотите использовать прокладки
Здесь лежит gotcha.. в вашем случае вы хотите использовать полосы без взрыва !
в то время как полосы! конечно, возвращает nil, если не было никаких действий, он по-прежнему обновляет переменную so strip! невозможно использовать inline. Если вы хотите использовать strip inline, вы можете использовать версию без взрыва !
ленту! использование многострочного подхода
> tokens["Title"] = " abc "
=> " abc "
> tokens["Title"].strip!
=> "abc"
> @title = tokens["Title"]
=> "abc"
прокладки один подход... ВАШ ОТВЕТ
> tokens["Title"] = " abc "
=> " abc "
> @title = tokens["Title"].strip if tokens["Title"].present?
=> "abc"
Я думаю, что ваш пример-разумный подход, хотя вы могли бы немного упростить его как:
@title = tokens[Title].strip! || tokens[Title] if tokens[Title]
альтернатива вы можете поставить его на две строки:
@title = tokens[Title] || ''
@title.strip!
Если вы хотите использовать другой метод после того, как вам понадобится что-то вроде этого:
( str.strip || str ).split(',')
таким образом, вы можете раздеться и все еще делать что-то после :)
если у вас есть ruby 1.9 или activesupport, вы можете сделать просто
@title = tokens[Title].try :tap, &:strip!
Это очень круто, так как он использует :try
и :tap
метод, которые являются самыми мощными функциональными конструкциями в ruby, на мой взгляд.
еще более симпатичная форма, передающая функции как символы в целом:
@title = tokens[Title].send :try, :tap, &:strip!
@title = tokens[Title].strip! || tokens[Title]
вполне возможно, что я не понимаю тему, но разве это не сделает то, что вам нужно?
" success ".strip! || "rescue" #=> "success"
"failure".strip! || "rescue" #=> "rescue"