String Manipulation Nuby Question

C

Chris Roos

I have a Person with title, forename and surname (all of which are
optional). I want to return a 'pretty' name for this person in the format..

title + <space> + forename + <space> + surname

..where any extraneous spaces are removed.

My name method currently looks like this

def name
(
(title.to_s.strip.empty? ? "" : title.to_s.strip << " ") <<
(forename.to_s.strip.empty? ? "" : forename.to_s.strip << " ") <<
(surname.to_s.strip.empty? ? "" : surname.to_s.strip)
).strip
end

I created seven tests for this method for each combination of the three
parameters. All seven tests pass with this implementation.

Note. I was half way through writing about how I should probably test
for nil and maybe return an empty string from the three (title,
forename, surname) methods when I realised that all I was really doing
was testing for nil in a roundabout way; i.e. convert possible nil's to
string then strip spaces then check for empty...

I started thinking about this some more and realised that a test for nil
would return false which would allow me to re-write the above method
like so..

def name
(
(title ? title.strip << " " : "") <<
(forename ? forename.strip << " " : "") <<
(surname ? surname.strip : "")
).strip
end

This gets rid of the nasty duplication and double question marks in the
first method.

I also realised that I needed another test - for all nil's. They all
still passed.

What I was originally going to ask was how to improve on the first
implementation above. Even though (in my opinion) the second
implementation is a lot cleaner I'm still interested in whether it can
be made even more succinct as in 'the ruby way'?

It may be a very small method and have taken me about an hour to go
through this process but I'm quite pleased as to how it's turned out.

Chris
 
D

David A. Black

Hi --

I have a Person with title, forename and surname (all of which are optional).
I want to return a 'pretty' name for this person in the format..

title + <space> + forename + <space> + surname

..where any extraneous spaces are removed.

My name method currently looks like this

def name
(
(title.to_s.strip.empty? ? "" : title.to_s.strip << " ") <<
(forename.to_s.strip.empty? ? "" : forename.to_s.strip << " ") <<
(surname.to_s.strip.empty? ? "" : surname.to_s.strip)
).strip
end
[...]
What I was originally going to ask was how to improve on the first
implementation above. Even though (in my opinion) the second implementation
is a lot cleaner I'm still interested in whether it can be made even more
succinct as in 'the ruby way'?

I'd let Ruby do more of the work, especially the iterating through the
items. Something like this might be suitable:

class Person
attr_accessor :title, :forename, :surname
def name
[title, forename, surname].compact.map {|s| s.strip }.join(" ")
end
end


David
 
C

Chris Roos

Thanks for coming back so fast. Unfortunately, this doesn't pass one of
the tests - where only a title and surname is supplied this
implementation will put two spaces in the middle...

"Mr Bloggs" instead of
"Mr Bloggs"

Chris
 
D

David A. Black

Hi --

"#{title} #{forename} #{surname}".strip

Much more succinct than mine :) You would, however, have to put a
squeeze(" ") in there too, to take out extra spaces in the middle.

" Mrs. Emma Peel ".squeeze(" ").strip
=> "Mrs. Emma Peel"


David
 
E

Eric Hodel

"#{title} #{forename} #{surname}".strip

This leaves spaces in the middle.

[title, forename, surname].join(' ').gsub(/ /, ' ')

require 'test/unit'

class TestFullName < Test::Unit::TestCase

def setup
@title = "Mr."
@surname = "Hodel"
end

def test_strip
assert_equal "Mr. Hodel", "#{@title} #{@forename} #{@surname}".strip
end

def test_join_gsub
assert_equal("Mr. Hodel",
[@title, @forename, @surname].join(' ').gsub(/ /, '
'))
end

end
 
D

Dominik Schlütter

Hi,

Logan Capaldo said:
"#{title} #{forename} #{surname}".strip

But that would leave double spaces in the middle if 'forename' was
empty, wouldn't it?


Regards,

Dominik.
 
C

Chris Roos

David said:
Hi --

I have a Person with title, forename and surname (all of which are
optional). I want to return a 'pretty' name for this person in the
format..

title + <space> + forename + <space> + surname

..where any extraneous spaces are removed.

My name method currently looks like this

def name
(
(title.to_s.strip.empty? ? "" : title.to_s.strip << " ") <<
(forename.to_s.strip.empty? ? "" : forename.to_s.strip << " ") <<
(surname.to_s.strip.empty? ? "" : surname.to_s.strip)
).strip
end
[...]

What I was originally going to ask was how to improve on the first
implementation above. Even though (in my opinion) the second
implementation is a lot cleaner I'm still interested in whether it can
be made even more succinct as in 'the ruby way'?


I'd let Ruby do more of the work, especially the iterating through the
items. Something like this might be suitable:

class Person
attr_accessor :title, :forename, :surname
def name
[title, forename, surname].compact.map {|s| s.strip }.join(" ")
end
end


David
Hmm, an hours work and a five line implementation replaced by one line a
matter of minutes... I have a long way to go ;-)

Thanks for your help.
 
L

Logan Capaldo

Ok Ok I admit it! I forgot the squeeze! ;-)
To reiterate:
"#{title} #{forename} #{surname}".strip.squeeze
 
D

David A. Black

Hi --

Ok Ok I admit it! I forgot the squeeze! ;-)
To reiterate:
"#{title} #{forename} #{surname}".strip.squeeze

It's got to be squeeze(" "). Otherwise:

" Mrs. Emma Peel ".strip.squeeze
=> "Mrs. Ema Pel"


David
 
C

Chris Roos

David said:
Much more succinct than mine :) You would, however, have to put a
.squeeze(" ") in there too, to take out extra spaces in the middle.

" Mrs. Emma Peel ".squeeze(" ").strip
=> "Mrs. Emma Peel"


David

Cool. Thanks again.
 
L

Logan Capaldo

Ooops, one more mistake in my iteration, stop listening to me
everyone! "#{title} #{forename} #{surname}".strip.squeeze(' ')
 
J

James Britt

Chris said:
Hmm, an hours work and a five line implementation replaced by one line a
matter of minutes... I have a long way to go ;-)

Yeah, but it's a great trip and you have excellent company.


James
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top