Learning Kotlin: by

Note * This is the 25th post in a multipart series. If you want to read more, see our series index * Koans used here are 34 and 35

The fourth set of Koans examines properties, and the first two focus on getters and setters. If you're coming from another programming language, these should work as you expect. This post will explore the amazing by keyword in the third and fourth examples. The by keyword lets us delegate the getter/setter to a separate class, allowing common patterns to be extracted and reused. Out of the box, there are five built-in options—which I’ll cover in their own posts—but for now, let’s build our own delegate class.

In this example, we can assign any value, but the result we always get is HAHAHA. We could store the result in the instance and return the assigned value, but we don’t have to. The key takeaway is that we’ve centralized the logic for our properties in one reusable place instead of scattering it across multiple getters and setters.

import kotlin.reflect.KProperty

class User {
    var name: String by Delegate()
    var eyeColour: String by Delegate()
}

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty): String {
        println("$thisRef, thank you for delegating '${property.name}' to me!")
        return "HAHAHA"
    }

    operator fun setValue(thisRef: Any?, property: KProperty, value: String) {
        println("$value has been assigned to '${property.name}' in $thisRef.")
    }
}

fun main(args: Array<String>) {
    val user = User()
    user.name = "Robert"
    user.eyeColour = "Green"
    println("My word ${user.name} but your eyes are ${user.eyeColour}")
}

Learning Kotlin: todo

Note This is the 24th post in a multipart series. If you want to read more, see our series index.

This post will be shorter than normal, as we are looking at a small feature that is easy to explain but can have major impacts on your codebase—that is, the todo function. To use it, you simply call it and optionally pass in a string that explains why the code isn’t done. For example:

fun main(args: Array<String>) {
    todo("Haven't started")
}

This will throw a NotImplementedError when encountered. What I like about this is that we are being explicit about the intent. Additionally, it makes it easy to find in your IDE of choice.


Learning Kotlin: The .. operator

Note This is the 23rd post in a multipart series. If you want to read more, see our series index.

The code for this can be found on GitHub.

No, I didn’t forget what this operator is and just put two dots in place of it. The operator we’re looking at is really ..! This operator pairs very nicely with the in operator we looked at previously in that it allows us to easily create an instance of a class that can define a range. Let’s look at a real example we’ve already used to help clarify this: 1..10. What we have there is an Int, then the operator, then another Int, and when we do that, we get an instance of ClosedRange. This is done by saying that if you ask for a range of Ints, you get a different class that knows how to store the start and end Ints and work out the parts in that range. This is implemented with the rangeTo operator function, which is added to the Int class.

In the same way that Ints support this, we can use it with custom classes too. If we look at the previous post about the in operator, we see that we’re using a custom class called MyDate to represent a date value. We also have a DateRange class to represent the start and end dates, and we could check if a value fell in that range with this code:

fun checkInRange(date: MyDate, first: MyDate, last: MyDate): Boolean {
    return date in DateRange(first, last)
}

If we add the rangeTo operator to the MyDate class and have it return a DateRange, like this:

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) {
    operator fun rangeTo(other: MyDate) = DateRange(this, other)
}

We can now change our previous example to support the .. operator:

fun checkInRange(date: MyDate, first: MyDate, last: MyDate): Boolean {
    return date in first..last
}

It compiles to the exact same code, but it just looks so much better!


Slides: Features of Kotlin I find exciting

A few weeks ago I was honored to speak at the first Developer User Group meetup in Cape Town, and it is no surprise—though I am sure some would be surprised—that I spoke for about 15 minutes on what my favorite features in Kotlin are. Thank you to all who attended, and if you are looking for the slides, they can be found below! They look broken, but this is because SlideShare can’t handle animation, so be sure to download them to check them out.

If you are interested in more Kotlin talks, I will be speaking next week at the Facebook Developer Circle for over an hour, giving an introduction to Kotlin. It’s going to be a great session—I am biased, though—so I do hope you join me!


Learning Kotlin: Looking at the In Operator & Contains

Note * This is the 22nd post in a multi-part series. If you want to read more, see our series index. * The code for this can be found here.

One of my absolute favorite features in Kotlin is ranges. You can easily go 1..10 to get a range of numbers from one to ten. In addition, so much of the way I find I want to work with Kotlin is around working with collections like lists and arrays. With all of those, we often want to know when something exists inside the range or the collection—and that’s where the in operator comes in. In the following example, we use the in operator to first check for a value in an array, then in a range, and then a substring in a string; each example below will return true:

val letters = arrayOf("a", "b", "c", "d", "e")
println("c" in letters)
println(5 in 1..10)
println("cat" in "the cat in the hat")

Naturally, Kotlin lets us add this to our classes too. The example from the Koans starts with a class that represents a range of dates:

class DateRange(val start: MyDate, val endInclusive: MyDate)

We then add an operator function named contains that checks if the value provided falls between the two dates of the class:

class DateRange(val start: MyDate, val endInclusive: MyDate) {
    operator fun contains(d: MyDate) = d in start..endInclusive
}

The security risk that is the humble link in your webpages

tl;dr: When adding the target attribute to an a element which takes you to a property you do not own, you must add rel="noopener noreferrer".

Info

When you open a link using target, for example in a new tab (target="_blank"), the browser may—though not universally—set the window.opener of the new tab to be the original window. This means that the new tab can access some information from the original window or tab.

If it is on the same domain, this is particularly risky, as it includes cookies and content. If it is on a different domain, the same-origin policy protects most information, though some details may still be exposed.

Attack Vectors

These attack vectors are targeted and do not represent a major risk, but the cost of mitigation is low. Here’s why I recommend taking precautions.

Same Domain

It’s not uncommon for a single domain to host pieces built by multiple teams, especially as web components gain traction. A vulnerability in one team’s code can now impact the entire domain.

For example:

  • https://badsite.com/login.html is built by teamA and handles authentication.
  • https://badsite.com/products.html is built by teamB and lists products publicly.

If the login page links to products.html with target="_blank", malicious JavaScript in the products page could manipulate the login page—silently stealing credentials or injecting unwanted behavior.

This is also a strong case for using sub-resource integrity, especially when loading JS, CSS, or other assets via CDN.

Additionally, document.domain can grant elevated access to superdomains—but note that cookies remain protected post-changes.

Different Domain

While data is more locked down here, two attack vectors still exist:

Location Changes

The parent window/tab’s location can be altered. An attacker could:

  • Redirect the original tab to a vulnerable page.
  • In a phishing attack, make it appear identical to a trusted site (e.g., a bank).

Example: You click a link from your bank’s site to a third party. If that third-party page (either intentionally or via a compromised CDN) detects the referring bank’s URL, it could silently redirect you to a fake login page. You return to the tab, unaware it’s now malicious, and unknowingly compromise your credentials.

postMessage

The postMessage API allows cross-domain communication. If the parent page uses it and contains vulnerabilities, a new tab could exploit them to gain unintended privileges.

Solution

Add rel="noopener noreferrer" to links with target="_blank" to prevent window.opener from being set unless you explicitly trust the destination property.

<a href="..." target="_blank" rel="noopener noreferrer">Safe link</a>

Learning Kotlin: Invoke

More Information This is the 21st post in a multipart series. If you want to read more, see our series index

Today we tackle a weird operator, invoke, which lets an instance of a class have a default function—something I’m not sure I’ve ever seen any language do. Let’s frame this with a simple example: we have a Config class that returns configuration for something:

class Config {
    fun get(): String { // do stuff
        return "stuff"
    }
}

fun main(args: Array<String>) {
    val config = Config()
    println(config.get())
}

Now, in our world, maybe get is the primary use, so we can make it so that the instance config (line 9) can be called directly to get it:

class Config {
    operator fun invoke(): String {
        return this.get()
    }

    private fun get(): String { // do stuff
        return "stuff"
    }
}

fun main(args: Array<String>) {
    val config = Config()
    println(config())
}

Note: we add a new operator (line 2), and it calls the private get—though it didn’t need to be private, I thought this would be cleaner. Now, on line 14, we can just call the instance itself.

Now, you might be thinking… nice, but so what? Saving a few keystrokes isn’t that awesome. Well, invoke can return anything—even itself—opening up something truly powerful.

class Config {
    var count = 0

    operator fun invoke(): Config {
        count++
        return this
    }
}

fun main(args: Array<String>) {
    val config = Config()
    config()()()()()()()()()()
    println("config was called ${config.count} times")
}

This will print out: config was called 10 times

That’s getting more interesting, so let’s ramp up another level and pass parameters to invoke:

class Config {
    var word = ""

    operator fun invoke(s: String): Config {
        word += s
        return this
    }
}

fun main(args: Array<String>) {
    val config = Config()
    config("R")("o")("b")("e")("r")("t")
    println(config.word)
}

While I don’t yet know where I’d use this myself, I do use invoke all the time… since it’s what makes lambdas possible in Kotlin. When we create a lambda, we get an object that’s invoked with—well—invoke.


Learning Kotlin: The For Loop

Note This is the 20th post in a multipart series. If you want to read more, see our series index.


Kotlin has two loops: while and for. When I started, I was like, "yup, I know those..."—except I didn’t. while works the way I expected it would, but for is something else. First, Kotlin doesn’t have a traditional for loop, like for (var i = 0; i < max; i++). Instead, the for loop in Kotlin is closer to the iterator foreach loop in C#.

Basic

Let’s start with the basics: how do I run a loop, say, 10 times, where we print out 0, 1, 2, 3, 4, 5, 6, 7, 8, 9?

fun main(args: Array<String>) {
    for (i in 0..9) {
        println(i)
    }
}

In this example, we use a ClosedRange (0..9) to state the start and end of the loop. This is equivalent to for (var i = 0; i < 10; i++).

Now, normally we want to loop over an array of items, and we can do this in two ways. First, the equivalent of C#’s for iterator or JavaScript’s for...of:

fun main(args: Array<String>) {
    val a = arrayOf("The", "Quick", "Brown", "Fox")
    for (i in a) {
        println(i)
    }
}

And if we use the older style of a normal for loop with an index:

fun main(args: Array<String>) {
    val a = arrayOf("The", "Quick", "Brown", "Fox")
    for (i in 0 until a.size) {
        val value = a[i]
        println(value)
    }
}

What’s awesome here is the Range. Unlike the inclusive bounds of .., the until keyword gives us an exclusive upper bound.

Kotlin is all about helpers, and since we looked at destructuring last time, it shouldn’t be a surprise that we can use it to include both the index and the value in the for loop:

fun main(args: Array<String>) {
    val a = arrayOf("The", "Quick", "Brown", "Fox")
    for ((i, value) in a.withIndex()) {
        println("$i is $value")
    }
}

Extras

The for loop has two additional options worth knowing:

  • downTo, which loops from largest to smallest. This example prints 4321:
    for (i in 4 downTo 1) print(i)
    
  • step, which controls how many steps to take between iterations. In this example, we get 42:
    for (i in 4 downTo 1 step 2) print(i)
    

Operator Overloading

Adding support for this to our own classes is trivial—just add the Iterator interface. This introduces two methods:

  • fun next(): T (returns the next value in the collection)
  • fun hasNext(): Boolean (returns true if more values exist)

Let’s implement this with a PrimeNumbers class. Since there are infinite primes, we’ll add a top bound (maxToHunt), which forces the loop to eventually end. In next(), we not only return the current prime but also calculate the next next value to efficiently track whether more primes exist.

class PrimeNumbers : Iterator<Int> {
    var currentPrime = 1
    val maxToHunt = 100
    var morePrimesToFind = true

    override fun next(): Int {
        val result = this.currentPrime
        this.currentPrime += 1
        while (this.currentPrime < this.maxToHunt) {
            var primeFound = true
            for (divisor in this.currentPrime - 1 downTo 2) {
                if (this.currentPrime % divisor == 0) {
                    this.currentPrime += 1
                    primeFound = false
                    break
                }
            }
            if (primeFound) break
        }
        this.morePrimesToFind = this.currentPrime < this.maxToHunt
        return result
    }

    override fun hasNext() = this.morePrimesToFind
}

fun main(args: Array<String>) {
    for (i in PrimeNumbers()) {
        println("$i is prime")
    }
}

Learning Kotlin: Destructuring

Note This is the 19th post in a multi-part series. If you want to read more, see our series index.

Learning a new language seems to be an experience you have to:

  1. change jobs,
  2. cause your boss made you do it, or
  3. cause you are a nerd. The thing I forget each time I learn a new language is that the act of learning a new language helps me be a better software developer in my primary language (the secret fourth option). Going through Kotlin has been a similar experience, and nothing jumped out more than object destructuring.

The simple use for object destructuring is to be able, in a single line, to assign multiple variables from an object. Let’s look at this example:

data class Person(val firstName: String, val surname: String, val age: Int)

fun name(person: Person) {
    println("Hi ${person.firstName}")
}

fun name2(person: Person) {
    println("Hi ${person.firstName} ${person.surname}")
}

fun main(args: Array<String>) {
    val frank = Person("Frank", "Miller", 61)
    val alan = Person("Alan", "Moore", 64)
    name(frank)
    name2(frank)
    name(alan)
    name2(alan)
}

In each of the name and name2 functions, I’m working with the Person object—but all I want are the names. I never care about the age of the people.

We could add a function now, which pulls out just the strings we want and modifies everything else to work with just the data it needs:

data class Person(val firstName: String, val surname: String, val age: Int)

fun name(firstName: String) {
    println("Hi $firstName")
}

fun name2(firstName: String, surname: String) {
    println("Hi $firstName $surname")
}

fun print(person: Person) {
    val (firstName, surname) = person
    name(firstName)
    name2(firstName, surname)
}

fun main(args: Array<String>) {
    val frank = Person("Frank", "Miller", 61)
    val alan = Person("Alan", "Moore", 64)
    print(frank)
    print(alan)
}

Line 12 is the magic—that’s object destructuring. Rather than having two lines where we assign a variable to firstName and surname, we can assign them both in one line, so long as they are wrapped in parentheses and match the names of the object’s properties.

So, why is this useful for other languages? Cause in JavaScript, you have the same thing! The only difference is {} instead of parentheses—and since learning it in Kotlin, I’ve found that I use it in my main code too.


VS Code Extension of the Day: Paste JSON as code

Note * This is the 8th post in a multipart series. If you want to read more, see our series index.

You have some data in JSON and want a class to work with it in TypeScript, Python, Go, Ruby, C#, Java, Swift, Rust, Kotlin, C++, Flow, Objective-C, JavaScript, or Elm? You could do it by hand—or get this extension, which does it for you. And if you don’t use VSCode (why are you here?), they also have a website which can do this for you too. Learn more and download it.