Variables

Explains how variables behave in exolynk scripts.

Variables in Rune the Exolynk Scripting language are defined using the let keyword. All variables in Rune are mutable and can be changed at any time.

#[test]
pub fn test() {
    let x = 5;
    assert_eq!(5, x);
    x = 6;
    assert_eq!(6, x);
}

In Rune there are two kind of variable types: Shared and Primitives.

Shared Variables

Shared Variables are reference counted and can be used at multiple locations at the same time. This means that they have shared ownership. Every variable that points to that value therefore points to the same instance of that value.

#[test]
pub fn test() {
    let object = #{ field: 1 };
    let object2 = object;
    println!("{}", object.field);
    object2.field = 2;

    // Note: we changed `object2`, but read out `object`
    assert_eq!(2, object.field);
}

This behaviour can cause issues if we call an external function which expects to take ownership of its arguments. We say that functions like these move their argument, and if we try to use a variable which has been moved an error will be raised in the virtual machine.

pub fn test() {
    let object = #{ field: 1 };
    let object2 = object;
    println!("field: {}", object.field);
    // move the variable into the drop function and consume it
    drop(object2);
    // This will fail, because object was also consumed in the line above
    println!("field: {}", object.field);
}

If you need to, you can test if a variable is still accessible for reading with is_readable, and for writing with is_writable. These are both imported in the prelude. An object which is writable is also movable, and can be provided to functions which need to move the value, like drop.

#[test]
pub fn test() {
    let object = #{ field: 1 };
    let object2 = object;
    println!("field: {}", object.field);
    drop(object2);
    assert!(!is_readable(object));
}

Primitive Variables

Primitives are values stored immediately on the stack. So reassigning them to different values will create distinct copies of the underlying value.

The primitives available in Rune are:

  • The unit ().
  • Booleans, true and false.
  • Bytes, like b'\xff'.
  • Characters, like '今'. Which are 4 byte wide characters.
  • Integers, like 42. Which are 64-bit signed integers.
  • Floats, like 3.1418. Which are 64-bit floating point numbers.
  • Static strings, like "Hello World".
  • Type hashes.
#[test]
pub fn test() {
    let a = 1;
    let b = a;
    a = 2;
    assert_eq!(a, 2);
    assert_eq!(b, 1);
}