Format

  • ::A
  • ::A()
  • A::B
  • A::B() (proc reference, not a call; see below)

This is the scope operator. It has multiple uses.

Global var and proc disambiguation

::A is a shorthand for global.A, so if you have a local or object var with the same name this disambiguates to the global var. The same is true of :A() which will call global.A() with the arguments you give it.

Static var disambiguation

If A is a constant type and B is a static var, A::B refers to the static var. If you have a local var with the same name, this disambiguates to the static var. This is also the only case where A::B can be used as an Lvalue (modifiable expression).

Initial value

The most common use of the scope operator is to get the initial value for a var. If A::B isn’t a static var, then it’s equivalent to initial(A:B). If A is a constant type path, the compiler will go even further by compiling this expression as the actual initial value instead of doing a runtime lookup.

This can also be used when defining a var that overrides its parent, by using the parent_type keyword for A. Multiple parent_type levels can be chained together. Similarly, in a static var definition, type can be used for A the same way.

thing
    var/price = 60
    better
        price = parent_type::price + 40

Proc reference

If B is a proc, then A::B() is a reference to the proc for type A, which can be used in call(). In this case the parentheses are just a cue for the compiler to know this is a proc reference; it doesn’t actually call the proc. Currently, A must be a constant type for this usage.

thing
    proc/DoSomething()
        world << "Did a thing"
    better
        DoSomething()
            world << "Did a better thing"
 
proc/Downgrade()
    var/thing/better/T = new
 
    // will print "Did a better thing" because T is /thing/better
    T.DoSomething()
 
    // deliberately calls /thing's original version; will print "Did a thing"
    call(T, /thing::DoSomething())()

See also