Reputation: 95
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).
Upvotes: 1
Views: 133
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