1

I have this helper to simplify null asserts:

object Helpers {
  implicit class NotNullAssert[T](val obj: T) extends AnyVal {
    def ! : T = {
      assert(obj != null); obj
    }
  }
}

Now I am trying to use it:

import Helpers._

class Name(val first: String, val last: String) {
  val full = first! + " " + last!
}

Getting a compilation error:

Error:(8, 27) value unary_+ is not a member of String
               val full = "" + first! + " " + last!

The same time, the following works:

val full = first! //+ " " + last!

What is going wrong in the fragment above?

2
  • 1
    first! is "post-fix notation" and confuses the compiler when used in longer expressions. Try first.! and see what happens. Commented Apr 13, 2018 at 21:56
  • 1
    ... or (first!) Commented Apr 13, 2018 at 22:24

3 Answers 3

2

Postfix operators tend not to play well with binary infix operators. However, you might want to define ! as an unary operator that should be used in prefix position:

def unary_! : T = {
  assert(obj != null); obj
}

Then this here works:

val full = !first + " " + !last

But please be careful with this, probably nothing good will happen when you try to use it with boxed booleans or other types that support unary !. When in doubt, just use . or parentheses.


An aside about the usage of .!-syntax: when using sys.process, it's rather common to write cmd.! and cmd.!!, so keeping your definition and using .! wouldn't look "too weird".

Sign up to request clarification or add additional context in comments.

Comments

1

With mkString it works:

import Helpers._

class Name(val first: String, val last: String) {
  val full = List (first!, last!).mkString (" ")
}

Comments

1

I think if you follow the rules in Prefix, Infix, and Postfix Operations

"" + first! + " " + last!

gets parsed as

"".+(first).!(+ " ").+(last).!

and then it can't find the unary_+ required for + " ".

This transformation happens at the parsing stage, and so doesn't know anything about what methods are available.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.