3

In Kotlin I have this function to wrap a transaction:

fun wrapInTransaction(code: () -> Unit) {
        realmInstance.beginTransaction();
        code.invoke()
        realmInstance.commitTransaction();
}

How can I get access to realmInstance in the invoked code?

1

3 Answers 3

3

The easy solution here is to make code a function with receiver:

fun wrapInTransaction(code: Realm.() -> Unit) {
    realmInstance.beginTransaction();
    realmInstance.code()
    realmInstance.commitTransaction();
}

Inside a lambda which you pass as code you will be able to use this to reference the RealmInstance and to use its members directly as if inside a member function.

Calling realmInstance.code() is just calling code with passing realmInstance as a receiver to it.

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

1 Comment

It's even better to make the whole function an extension function.
2

The other answers correctly demonstrate how to pass the RealmInstance object to the lambda. In addition, you can make the whole function an extension function which makes the call site a bit prettier:

fun Realm.wrapInTransaction(code: Realm.() -> Unit) {
    //this is implicit
    beginTransaction();
    code()
    commitTransaction();
}

The call site will look like this:

Realm.getInstance(this).wrapInTransaction {
    createObject(User.class)
}

Comments

1

Change the wrapInTransaction function to accept an extensions method on realmInstance like so:

fun wrapInTransaction(code:Realm.() -> Unit){
    realmInstance.beginTransaction();
    realmInstance.code()
    realmInstance.commitTransaction();
}

Then you can use it like:

wrapInTransaction {
    println("realm instance is $this, instanceId: $instanceId")
}

Where for the sake of the example the Realm looks like:

class Realm {
    val instanceId = 42
    fun beginTransaction() {
    }

    fun commitTransaction() {
    }
}

The above technique is possible thanks to Kotlin's Function Literals with Receiver that make it possible to set the this instance (receiver) within lambda function body. It makes it easy to build type safe builders that reassemble ones from Groovy or Ruby.

This answer provides more samples on the technique.

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.