Skip to content
December 9, 2008 / Abe Pralle

Understanding class members and singletons

Here’s a bit of background on class members and singletons to flesh out my previous post on automatic singletons.

First let’s look at regular classes and objects.  A class defines how an object behaves and what properties it has.  If we wanted to make an adventure-RPG we might define classes for Torch, Horse, Ration, Weapon, and others.  In Slag:

class Torch
  PROPERTIES
    minutes_left : Real64
    is_lit : Boolean

  METHODS
    method init( is_lit=false, minutes_left=30.0 ):

    method light:
      if (minutes_left > 0.0) is_lit = true

    method tick:
      minutes_left = minutes_left - 1.0
      if (minutes_left <= 0.0) is_lit = false
endClass

Now we can create as many torch objects as we want – each one is different:

    wall_sconce_1.place( Torch(true) )
    wall_sconce_2.place( Torch(false,20.0) )
    hero.inventory.add( Torch() )

The wall sconces have, respectively, a lit torch that will burn for 30 minutes and an unlit torch that would burn for 20 minutes, while the hero has an unlit torch that would burn for 30 minutes in their inventory.

Each torch has its own properties (or object properties; also instance variables in Java).  A torch could also have class properties (Java: static variables) that apply to all torches.  A common use is to use them for default settings:

    class Torch
      CLASS_PROPERTIES
        default_longevity=30.0 : Real64
      ...
      METHODS
        method init( is_lit=false, minutes_left=default_longevity ):
        ...
    endClass
    ...
    wall_sconce_1.place( Torch(true) )
    Torch.default_longevity = 20.0
    wall_sconce_2.place( Torch() )
    hero.inventory.add( Torch() )

Now the second wall sconce and the hero both have an unlit torch that would burn for 20 minutes.

A class method (aka static method) is a method that can be called directly on the class instead of on objects of the class – it is most frequently used to accomplish tasks related to a class of object but not requiring any specific object to work with – often class methods are used as factory methods to create an object and set it up for you to avoid having to repeat the same setup logic over and over.  For example, if we always wanted to create a lit torch if it’s night or an unlit torch if it’s day, we could do this every time you create a torch:

    if (world.is_daytime) wall_sconce_1.add( Torch(false) )
    else wall_sconce_2.add( Torch(true) )

Or we could use a factory method:

    wall_sconce_1.add( Torch.create )

Which would be defined like this:

    class Torch
      ...
      CLASS_METHODS
        method create.Torch:
          if (world.is_daytime) return Torch(false)
          else return Torch(true)
      ...
    endClass

Now finally we can talk about singletons.  Sometimes you only ever want one copy (instance) of a certain class – like the King’s Castle.  There can be only one!  So the KingsCastle class will have a class variable that references the single KingsCastle object that’s ever created – furthermore, we’ll call a class method get_instance that creates the singleton if it doesn’t exist yet and returns it either way:

    class KingsCastle
      CLASS_PROPERTIES
        instance : KingsCastle

      CLASS_METHODS
        method get_instance.KingsCastle:
          if (instance is null) instance = KingsCastle()
          return instance

      PROPERTIES
        state_of_repair=100.0 : Real64
        gold=386 : Int32
      ...
    endClass
    ...
    hero.inventory.add( Torch() )
    hero.ride( Horse() )
    hero.travel_to( KingsCastle.get_instance )

Now, if that’s still a little confusing – well, that’s my point about automatic singletons is that all this is pretty confusing when you’re starting out and there’s a better way!  In Slag gen2:

    singleton KingsCastle
      PROPERTIES
        state_of_repair=100.0 : Real64
        gold=386 : Int32
      ...
    endSingleton
    ...
    hero.inventory.add( Torch() )
    hero.ride( Horse() )
    hero.travel_to( KingsCastle )
Advertisements

3 Comments

Leave a Comment
  1. Timothy Goya / Jan 10 2009 8:06 pm

    There’s a couple of things I don’t get about the Factory Method part:
    1. The method seems to inherit the scope of the caller (or is ‘world’ a global?).
    2. Why use a factory method? Isn’t the whole thing equivalent to wall_sconce_1.add(!world.is_daytime)?

  2. Abe Pralle / Jan 11 2009 1:00 am

    1. Yeah, “world” would be some kind of global or singleton, or perhaps a class variable that’s initialized in omitted code. That part’s just pseudocode.

    2. Well world.is_daytime doesn’t give you a Torch object, which is what we’re adding to the sconce! But regardless, the essential idea is that with factory methods you can shift a bunch of setup checks (and just imagine a bunch of tedious setup instead of a simple boolean check) out of the constructor every time you create an object and into a single location.

Trackbacks

  1. Automatic singletons and eliminating class members « Abe’s Codeblog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: