From: Dossy Date: 2002-07-23T09:12:33+09:00 Subject: Re: Strings and member-operators On 2002.07.23, the Bare wrote: > I'm looking for a way to strip the quotes (and whitespace) off of a > string. Right now, I'm using: > > class String > def stripQuotes > s = sub( '^\"', " " ) > s.sub!( '\"$', " " ) > return s.strip! > end > end > > This hardly strikes me as the most elegant way. In particular, a nil is > returned if the string is unquoted, and the only way I can see to get > around this is by adding more regular expressions to check for the > existence of quotes. > > A problem I'm having is that I can't seem to figure out how to get at > the underlying string data (like an array) in a member function. > > On a related note, and regardless of any suggestions on how to do what I > want to do, how does one call a member operator in a member function? For fun, lets see if we can do this test-first: Lets write the first test: class StripQuotesTest < Test::Unit::TestCase def test_do_nothing assert_equal("foo", "foo".stripQuotes) end end It fails. No surprise. Lets write some code: class String def stripQuotes self end end Okay. The test passes. Not very interesting: by the name of the test, the test really doesn't do anything. So, lets write another test: class StripQuotesTest < Test::Unit::TestCase def test_do_nothing assert_equal("foo", "foo".stripQuotes) end def test_strip_doublequotes assert_equal("foo", "\"foo\"".stripQuotes, "didn't remove outer double quotes") assert_equal("\"foo", "\"foo".stripQuotes, "incorrectly removed leading unmatched quote") assert_equal("foo\"", "foo\"".stripQuotes, "incorrectly removed trailing unmatched quote") assert_equal("f\"oo", "f\"oo".stripQuotes, "incorrectly removed inner double quote") end end Of course, the test fails because it didn't remove the outer quotes. Lets write some code: class String def stripQuotes unless (self =~ /^"(.*)"$/).nil? $1 else self end end end Cool. Tests pass again. Now, lets handle the stripping of whitespace with another test: class StripQuotesTest < Test::Unit::TestCase # previous cases omitted for brevity def test_strip_whitespace assert_equal("foo", "foo ".stripQuotes, "didn't strip trailing whitespace") assert_equal("foo", " foo".stripQuotes, "didn't strip leading whitespace") assert_equal("foo", " foo ".stripQuotes, "didn't strip leading and trailing whitespace") assert_equal("foo", "\" foo \"".stripQuotes, "didn't strip leading and trailing whitespace inside double quotes") assert_equal("\"foo\"", " \"foo\" ".stripQuotes, "incorrectly stripped double quotes") end end No surprise, the test doesn't pass. Write some more code: class String def stripQuotes unless (self =~ /^"(.*)"$/).nil? $1.strip else self.strip end end end The tests pass again, but the code's getting smelly. There's some visible duplication. Lets refactor: class String def stripQuotes self =~ /^"(.*)"$/ ($1 || self).strip end end There, eliminated the duplication. It still doesn't feel right -- now, we're not explicitly checking the success of the regexp match ... luckily we have unit tests to let us know if we make a mistake, though. I'm sure someone'll come up with an even more clever way of doing this, but at least I had fun doing it. ;-) -- Dossy -- Dossy Shiobara mail: dossy@panoptic.com Panoptic Computer Network web: http://www.panoptic.com/ "He realized the fastest way to change is to laugh at your own folly -- then you can let go and quickly move on." (p. 70)