constructorponylang

How do Pony constructors work?


It doesn't look like the Pony language has made many inroads to stack overflow yet, but you've gotta start somewhere...

Here's the very limited info about Pony constructors, which isn't helping me understand what I'm seeing.

Here's an initial program:

class Wombat
  let name: String
  var _hunger_level: U64

  new anon() =>
    name = "Anon"
    _hunger_level = 0

  new create(name': String) =>
    name = name'
    _hunger_level = 0

  new hungry(name': String, hunger': U64) =>
    name = name'
    _hunger_level = hunger'

actor Main
  new create(env: Env) =>

    env.out.print("Started.")

    let wombat: Wombat = Wombat("Ernie")
    let w: Wombat = createWombat()

    env.out.print("Name: "+wombat.name)
    env.out.print("Name: "+w.name)

  fun createWombat(): Wombat =>
    let w: Wombat = Wombat("Bert")
    w

Let's rename the "create" constructor to "named":

  new named(name': String) =>
    name = name'
    _hunger_level = 0

... and I see error:

Error:
/src/main/main.pony:22:26: couldn't find 'create' in 'Wombat'
    let wombat: Wombat = Wombat("Ernie")

... which suggests that all constructors are not created equal. Huh...?

So, let's undo that change.

Now let's try using the zero-arg constructor:

    let wombat: Wombat = Wombat()
    let w: Wombat = createWombat()

... and now I see:

Error:
/src/main/main.pony:22:33: not enough arguments
    let wombat: Wombat = Wombat()
                            ^

It's ignoring that constructor.

So, let's rename the first two constructors:

  new create() =>
    name = "Anon"
    _hunger_level = 0

  new named(name': String) =>
    name = name'
    _hunger_level = 0

... and now I see:

Error:
/src/main/main.pony:22:26: couldn't find 'apply' in 'Wombat'
    let wombat: Wombat = Wombat()

No idea what that means.


Solution

  • Thank you to Chris Double on the Pony mailing list.

    The answer is in the Syntactic Sugar docs. We simply need to specify which constructors we're running. So I changed the anon instantiation to:

    let wombat: Wombat = Wombat.anon()