Switchless enums in Dart - dart

I want to do something like this in Dart
enum Result {
dns,
dnf,
dnq,
finish,
active;
get description {
switch(this){
case dns: return 'Not Started';
case dnf: return 'Disqualified';
case dnq: return 'Disqualified';
case finish: return 'Finished';
case active: return 'Underway';
}
}
}
The above code works, but I'm bothered by the switch. I have an instinct that there should be a way to do this without the switch -- perhaps with a Map? But I can't figure out how.
I tried this
enum Result {
dns,
dnf,
dnq,
finish,
active;
final Map _description = {
dns: 'Not Started',
dnf: 'Disqualified',
dnq: 'Disqualified',
finish: 'Finished',
active: 'Underway'
};
get description => _description[this];
}
but that apparently won't work because dart says _description "depends on itself". I don't see how it does depend on itself any more than the version with the switch -- but hey, the compiler says so. Is this a dart bug, or am I missing something? Is there a better way to create enums that have auxiliary getters?
It would be great if there was a way that didn't require typing the enum identifiers twice and having to keep the copies aligned -- like, you know, an OO way.

You can do this like:
enum Result {
dns('Not Started'),
dnf('Did Not Finish'),
dnq('Disqualified'),
finish('Finished'),
active('Underway');
const Result(this.description);
final description;
}

Related

mql4 } not all control paths return a value

I have taken this function from another mql4 script. The other script compiles absolutely fine with no error. Strangely, now that I have copied this function into my script I get the error } not all control paths return a value
I understand the concept of return a value but not sure when there is a compile difference between the scripts
int ModifyOrder(int ord_ticket,double op, double price,double tp, color mColor)
{
int CloseCnt, err;
CloseCnt=0;
while (CloseCnt < 3)
{
if (OrderModify(ord_ticket,op,price,tp,0,mColor))
{
CloseCnt = 3;
}
else
{
err=GetLastError();
Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err));
if (err>0) CloseCnt++;
}
}
}
Most likely the difference is in #property strict. if using strict mode, you have to redeclare local variables, return value from every function (except void, of course) and some other differences.
In your example the function has to be ended with return CloseCnt; or maybe something else.
No way to declare non-strict mode - simply do not declare the strict one.
Once you declared it, it is applied to that file, and included into other files if importing.

Multiple types for a single variable (parameter/return type)

I am very new to Dart so excuse me if I didnt see this part.
I want to make a union type e.g. for a function input. In TS this would be:
let variableInput: string | number
typedef doesnt really define types but functions and enums dont really help too.
On the other side how should it look like when a function return either one or the other of two types? There must be something I dont see here.
There are no union types in Dart.
The way to do this in Dart is returning/accepting dynamic as a type:
dynamic stringOrNumber() { ... }
void main() {
final value = stringOrNumber();
if (value is String) {
// Handle a string value.
} else if (value is num) {
// Handle a number.
} else {
throw ArgumentError.value(value);
}
}
See also: https://dart.dev/guides/language/sound-dart

Rascal AST visit access annotation

Ok, so I would like to access a node's annotations when I visit it. To give an example:
visit (myAST) {
case someNode(str name): {
// How do I now access the #src annotation of someNode here?
}
};
I have already tried the following but this does not work:
visit (myAST) {
case someNode(str name): {
parents = getTraversalContext();
iprintln(parents[0]); // This print shows someNode with the #src annotation.
iprintln(parents[0]#src); // This gives the error: get-annotation not supported on value at...
}
};
What am I doing wrong here? Is my approach wrong?
Good question, the best way to do this is to introduce a variable, say sn in the pattern and to use that to fetch the annotation
visit (myAST) {
case sn:someNode(str name): {
// Access the #src annotation of someNode here by sn#src
}
};
As a side note: you use the function getTraversalContext but I strongly advice you to avoid it since it is experimental and will very likely change in the future. Admitted: we should have marked it as such.

Mocking with Dart - How to filter logs when a callsTo argument

I'm wondering if it's possible to filter logs by properties of passed arguments to a specific function. To be more specific, here's where I'm starting:
_dispatcher.getLogs(callsTo("dispatchEvent", new isInstanceOf<PinEvent>()));
I'd like to further filter this by PinEvent.property = "something"
In pseudo-code, I guess it'd look like this:
_dispatcher.getLogs(callsTo("dispatchEvent", new isInstanceOf<PinEvent>("property":"something")));
Any ideas? I know I can loop through the entire log list, but that seems dirty, and I would think there'd be a better way.
Thanks :-)
You can write your own matcher and use it instead of isInstanceOf
or derive from isInstanceOf and extend this matcher with the missing functionality.
I don't know of a matcher that does this out of the box (but I must admit that I didn't yet work very much with them).
While waiting for responses I whipped this up real quick. It's probably not perfect, but it does allow you to combine an isInstanceOf with this matcher using allOf. ex:
allOf(new isInstanceOf<MyThing>(), new ContainsProperty("property", "propertyValue"));
And here's the Matcher:
class ContainsProperty extends Matcher {
final String _name;
final dynamic _value;
const ContainsProperty(String name, dynamic value):this._name = name, this._value = value;
bool matches(obj, Map matchState) {
try {
InstanceMirror objMirror = reflect(obj);
InstanceMirror propMirror = objMirror.getField(new Symbol(_name));
return propMirror.reflectee == _value;
} catch (e) {
return false;
}
}
Description describe(Description description) {
description.add("contains property \"${_name}\" with value \"${_value}\"");
}
}

Constraint cannot be special class 'System.Object'

My function requires you pass it a string and a Type as T. Based on T i want to parse the string val as that type, but I get the error from the title of this question. Anyone that has any insight or other ways of accomplishing this function, I would greatly appreciate it.
T Parse<T>(string val) where T : System.Object
{
TypeCode code = Type.GetTypeCode(typeof(T));
switch (code)
{
case TypeCode.Boolean:
return System.Boolean.Parse(val);
break;
case TypeCode.Int32:
return Int32.Parse(val);
break;
case TypeCode.Double:
return Double.Parse(val);
break;
case TypeCode.String:
return (string)val;
break;
}
return null;
}
Just remove where T : System.Object.
By stating:
where T : System.Object
you're saying that the types T usable in your method Parse must inherit from object.
But, since every object in C# inherits from System.Object you don't need that constraint (and probably that's one of the reasons why the compiler does not allow that).
Also, since you're returning null, you should constraint the type T to be a reference type, so:
where T: class
But in this way you can't return a boolean, integer or whatever value type.
However, your code basically mimics the functionality of Convert.ChangeType, the only difference is that you're using generics to return the correct type instead of object, but is basically equal to this:
T Parse<T>(string val)
{
return (T)Convert.ChangeType(val,typeof(T));
}

Resources