avanwieringen
avanwieringen

Reputation: 2444

What kind of Scala construct is this?

Sometimes when you are just learning a new language it is very difficult to find an answer to something very fundamental just because the search keywords are either very trivial (resulting in too many irrelevant search results) or I have no idea what keywords to use.

I was looking at the first movie from Jetbrains regarding their features of IntelliJ with Scala (https://www.youtube.com/watch?v=UJe4wPUtcUQ#t=235). In this frame you see this code:

test("Email with valid address") {
    val email = Email("[email protected]")
    assert(email.address != null)
}

This seems like an odd thing (coming from Java) and looking at the API docs of Scalatest.FunSuite I see that Funsuite is a functional test suite, but I am unable to find the function test in the docs of FunSuite (http://doc.scalatest.org/2.2.1/index.html#org.scalatest.FunSuite).

My guess was that the function test somehow requires you to define an anonymous function after it, but what does this mean? What does test return? Where can I find the API doc of test if not in the class FunSuite?

Upvotes: 3

Views: 124

Answers (2)

Ionuț G. Stan
Ionuț G. Stan

Reputation: 179119

You're having difficulties finding the test method in the API docs because, by default, non-public members are not show, and test is marked as protected.

enter image description here

If you click the "show all" button, the test method will appear in the list of members.

enter image description here

Expanding its docs will also show the trait where it is defined (Definition Classes FunSuiteLike).

enter image description here

Upvotes: 2

Chris K
Chris K

Reputation: 11917

The area that you should read into is Scala's support for passing functions as arguments to other functions. What you are looking at is Scala syntax for a function that returns a function that in turn takes another function as an argument (what a mouthfull!). Some code will make it clearer, the original Scala code is:

test("Email with valid address") {
    val email = Email("[email protected]")
    assert(email.address != null)
}

which is the same as

test("Email with valid address")( {
    val email = Email("[email protected]")
    assert(email.address != null)
} )   

Notice the extra brace, implying that the code block is being past as an argument to another function.

To help make this a little more concrete, in Java we might see it like this:

test("Email with valid address").apply( new Function0() {
    public void invoke() {
        val email = Email("[email protected]")
        assert(email.address != null)    
    }
}

Or in Java 8

test("Email with valid address").apply( 
    () -> {
        val email = Email("[email protected]")
        assert(email.address != null)    
    }
}

Notice that the Scala variation is quite concise and was designed to support extension of the language itself. Thus libraries can create APIs that look like language level syntax.

For more information, the following two blog posts will be useful: defining custom control structures and by name parameter to function

Upvotes: 5

Related Questions