Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I want to get just the first line of a big string. Currently, here's how I do it:

def getFirstParagraph(txt: String) = {
    val newLineIdx = txt.indexOf("\n") match {
        case i: Int if i > 0 => i
        case _               => txt.length
    }

    txt.substring(0, newLineIdx)
}

But my friend sees some downfall: if txt is null, there will be an exception. His suggestion involved using var:

def getFirstParagraph(txt: String) = {
    var result = txt
    scala.util.control.Exception.ignoring(classOf[Exception]) {
        result = result.substring(0, result.indexOf("\n"))
    }
    result
}

Which will handle the null value fine. Thing is, I'm quite uncomfortable using var. How can I handle this case without using var (aka the Scala / functional way)?

share|improve this question
    
Note that the second example is missing the equals sign, meaning the method will return Unit. –  Daniel C. Sobral Aug 13 '12 at 13:48
    
@DanielC.Sobral edited. thanks –  bertzzie Aug 13 '12 at 16:08
add comment

3 Answers

up vote 8 down vote accepted
scala> def getFirstParagraph(txt: String) = {
         Option(txt).map(_.takeWhile(c => c != '\n')).orNull
       }
getFirstParagraph: (txt: String)String

scala> getFirstParagraph(null)
res2: String = null

scala> getFirstParagraph("fsdfasf")
res3: String = fsdfasf

scala> getFirstParagraph("fsdfasf\nxxxxxxx")
res4: String = fsdfasf

Option(txt) converts txt into an Option[String] which will be None if txt is null.

map will execute the takeWhile only if the Option is Some.

Finally orNull will pull the value out of the Option if it is Some or evaluate to null otherwise.

share|improve this answer
    
This gives me a warning: "<console>:9: warning: comparing values of types Char and java.lang.String using `!=' will always yield true" on Sacla 2.9.2, also the code didn't work... –  bertzzie Aug 13 '12 at 4:03
    
Nevermind, silly mistake. I tested against "\n", not '\n'. Sorry. –  bertzzie Aug 13 '12 at 4:08
add comment

Here's my take on it:

def getFirstParagraph(txt: String): String = txt.lines.next

As to the null objection: in idiomatic Scala, you don't use null. If there's some API which might return you a null string, then, at that point, you turn it into an Option, and handle the Option elsewhere as needed.

Handling null (or even Option) at the getFirstParagraph method is misplaced.

share|improve this answer
    
I agree on the misplaced responsabilities note. –  fedesilva Aug 13 '12 at 23:00
    
Good point, I agree. –  ericacm Aug 14 '12 at 3:19
add comment

ericacm's code may be shortened (removing explicit lambda notation). Also, propagating null is a bad/dangerous thing (unless you are forced to stay close to the metal, but then how about writing in C), so why not return an Option?

def getFirstParagraph(txt: String) = {
    Option(txt).map(_.takeWhile(_ != '\n'))
}

Or, if you don't use this from Java, testing for null is kinda weird, as in pure world there is no null. So there is:

def getFirstParagraph(txt: String) = {
    txt.takeWhile(_ != '\n')
}
share|improve this answer
1  
In the second case map call is excess. –  citxx Nov 17 '12 at 15:12
    
Thank you for mentioning error. I was too careless. –  Sarge Borsch Nov 20 '12 at 14:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.