Kevin Kons
Kevin Kons

Reputation: 95

Netlogo Extensions API - How to alert user of error?

I am making an netlogo extension to add q-learning comportament to agents.

The developer must use the reporter state-def agentset [variables to be mapped] to tell the extension that it must map the specified variables of that breed as part of the state.

So the developer could use the extension this way:

extensions [qlearningextension]

breed [Creatures Creature]

Creatures-own [
  name
]

to setup
  ask patch 0 0 [
    sprout-Creatures 1 [
      set name "joao"
    ]
  ]
  show qlearningextension:state-def Creatures ["nameee"]
end

As the extensions owns a variable called name and the developer is passing "nameee" the extension will throw an exception saying that "Breed CREATURES doesn't own NAMEEE".

I want to know if there is a way that I can antecipate to the user that he did a mistake, by alerting him like netlogo does (Example in image).

enter image description here

Upvotes: 1

Views: 133

Answers (1)

Jasper
Jasper

Reputation: 2790

There are a few options I can think of.

Option 1

If you can get by with turtles-own variables (not breeds-own), then you can use the Syntax.ReferenceType in your primitive's system definition. When NetLogo sees this primitive, if will check that the argument is the name of a variable it knows about and give a compile-time error much like the balck one you presented.

Here is an example in Scala:

object ReferenceTypeTest extends api.Command {
  override def getSyntax =
    commandSyntax(
      right = List(ReferenceType),
      agentClassString = "-T--"
    )

  def perform(args: Array[api.Argument], context: api.Context) {
    val ref: Reference = args(0).asInstanceOf[org.nlogo.nvm.Argument].getReference
    println(ref.vn)
  }
}

The Reference value you get from the args gives you the variable number, vn, you can use with the agent's variable array to get or set values as needed.

One tricky thing is that NetLogo will validate the reference argument is to a real variable, but it will not confirm that the variable is for a particular agent or breed. You'll have to manually check at runtime that the user gave you a turtle variable if that's what you were expecting.

As I said, this does not appear to work with breeds-own variables. I'm not sure if that's intentional or an oversight, but it's unfortunate.

Option 2

Just throw a nice ExtensionException runtime error when you find the user has given an invalid variable name. If you do the checking yourself, you can be very explicit about why the value was incorrect. This obviously isn't as nice as a compile-time message, but it will be more helpful that some kind of generic argument not found exception. Here is an example from the Python extension where number values are checked for validity and errors thrown if not.

Option 3

Editing to add this one.

It's close to Option 1, just use SymbolType instead of ReferenceType, and use getSymbol to get the argument to perform the command. The symbol will have some token information. Like Option 1, this will not protect you from having incorrect variables given (so will still need runtime checks), but it will at least let users give breeds-own variable names to the primitive and have basic compile-time correctness checks done.

Upvotes: 1

Related Questions