views:

2433

answers:

3

This is what I have now - which looks too verbose for the work it is doing.

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

Assume tokens is a array obtained by splitting a CSV line. now the functions like strip! chomp! et. all return nil if the string was not modified

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

What is the Ruby way to say trim it if it contains extra leading or trailing spaces without creating copies?

Gets uglier if I want to do tokens[Title].chomp!.strip!

+2  A: 

Hi,

I guess what you want is:

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

The #strip! method will return nil if it didn't strip anything, and the variable itself if it was stripped.

According to Ruby standards, a method suffixed with an exclamation mark changes the variable in place.

Hope this helps.

Update: This is output from irb to demonstrate:

>> @title = "abc"
=> "abc"
>> @title.strip!
=> nil
>> @title
=> "abc"
>> @title = " abc "
=> " abc "
>> @title.strip!
=> "abc"
>> @title
=> "abc"
Igor
Hmm.. still I think @title = tokens[Title].strip! looks cleaner - its a pity it returns nil instead of the unmodified string. Unless someone posts a better ans.. you're getting the accepted bit.
Gishu
Well, @title = tokens[Title].strip will do the trick but you'd have a copy instead, which is fine if you keep the tokens[Title] variable untouched.
Igor
If you want a method to return the unmodified string, you could easily make your own: def strip_returning_self() strip! || self end
Chuck
@chuck Yeah. but I was hoping there was a neat trick to do that without rolling my own method.
Gishu
+1  A: 

I think your example is a sensible approach, although you could simplify it slightly as:

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

Alternative you could put it on two lines:

@title = tokens[Title] || ''
@title.strip!
Olly
+1  A: 

There's no need to both strip and chomp as strip will also remove trailing carriage returns - unless you've changed the default record separator and that's what you're chomping.

Olly's answer already has the canonical way of doing this in Ruby, though if you find yourself doing this a lot you could always define a method for it:

def strip_or_self!(str)
  str.strip! || str
end

Giving:

@title = strip_or_self!(tokens[Title]) if tokens[Title]

Also keep in mind that the if statement will prevent @title from being assigned if the token is nil, which will result in it keeping its previous value. If you want or don't mind @title always being assigned you can move the check into the method and further reduce duplication:

def strip_or_self!(str)
  str.strip! || str if str
end

As an alternative, if you're feeling adventurous you can define a method on String itself:

class String
  def strip_or_self!
    strip! || self
  end
end

Giving one of:

@title = tokens[Title].strip_or_self! if tokens[Title]

@title = tokens[Title] && tokens[Title].strip_or_self!
Daniel Aborg
Although not technically the answer. Thanks.. didn't know that..
Gishu