Каков канонический способ обрезать строку в Ruby без создания новой строки?

Это то, что у меня есть сейчас - это выглядит слишком много для работы, которую он выполняет.

@title        = tokens[Title].strip! || tokens[Title] if !tokens[Title].nil?

Предположим, что токены - это массив, полученный расщеплением строки CSV. теперь такие функции, как полоса! грызть! и др. все возвращают nil, если строка не была изменена

"abc".strip!    # => nil
" abc ".strip!  # => "abc"

Что такое Ruby, чтобы сказать, обрезать его, если он содержит дополнительные ведущие или конечные пробелы без создания копий?

Получается более уродливым, если я хочу сделать tokens[Title].chomp!.strip!

Ответ 1

Я предполагаю, что вы хотите:

@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"

Ответ 2

Btw, теперь рубин уже поддерживает только полосу без "!".

Для сравнения:

p "abc".strip! == " abc ".strip!  # false, because "abc".strip! will return nil
p "abc".strip == " abc ".strip    # true

Также невозможно strip без дубликатов. См. Источники в файле string.c:

static VALUE
rb_str_strip(VALUE str)
{
    str = rb_str_dup(str);
    rb_str_strip_bang(str);
    return str;
}

ruby ​​1.9.3p0 (2011-10-30) [i386-mingw32]

Обновление 1: Как я вижу сейчас - он был создан в 1999 году (см. rev # 372 в SVN):

Update2: strip! не будет создавать дубликаты - как в версиях 1.9.x, 2.x и trunk.

Ответ 3

Нет необходимости как в полосе, так и в chomp, поскольку полоска также удаляет возвращаемые возвраты каретки - если вы не изменили разделитель записей по умолчанию и то, что вы делаете.

Olly answer уже имеет канонический способ сделать это в 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!

Ответ 4

Если вы используете Ruby on Rails, есть squish

> @title = " abc "
 => " abc " 

> @title.squish
 => "abc"
> @title
 => " abc "

> @title.squish!
 => "abc"
> @title
 => "abc" 

Если вы используете только Ruby, вы хотите использовать strip

В этом заключается гоча.. в вашем случае вы хотите использовать полосу без взрыва!

в то время как полоса! конечно же, возвращает nil, если не было никакого действия, он все равно обновляет переменную, поэтому strip! не может использоваться inline. Если вы хотите использовать линейную линию, вы можете использовать версию без взлома!

strip!, используя многострочный подход

> tokens["Title"] = " abc "
 => " abc "
> tokens["Title"].strip!
 => "abc"
> @title = tokens["Title"]
 => "abc"

strip однострочный подход... ВАШ ОТВЕТ

> tokens["Title"] = " abc "
 => " abc "
> @title = tokens["Title"].strip if tokens["Title"].present?
 => "abc"

Ответ 5

Я думаю, что ваш пример - разумный подход, хотя вы можете немного упростить его:

@title = tokens[Title].strip! || tokens[Title] if tokens[Title]

Альтернативу вы можете поместить на две строки:

@title = tokens[Title] || ''
@title.strip!

Ответ 6

Мой способ:

> (@title = " abc ").strip!
 => "abc" 
> @title
 => "abc" 

Ответ 7

Если вы хотите использовать другой метод после того, как вам понадобится что-то вроде этого:

( str.strip || str ).split(',')

Таким образом вы можете удалить и сделать что-то после:)

Ответ 8

Если у вас есть ruby ​​1.9 или activesupport, вы можете сделать просто

@title = tokens[Title].try :tap, &:strip!

Это действительно круто, поскольку он использует методы :try и :tap, которые, по моему мнению, являются самыми мощными функциональными конструкциями в рубине.

Четная cuter форма, передающая функции как символы:

@title = tokens[Title].send :try, :tap, &:strip!

Ответ 9

@title = tokens[Title].strip! || tokens[Title]

Возможно, я не понимаю эту тему, но не сделает ли это то, что вам нужно?

" success ".strip! || "rescue" #=> "success"
"failure".strip! || "rescue" #=> "rescue"