I have a metamodel in which I have a class Range with min a max integer values and I want to define an xText DSL, in which you can define a range like 1..10, but also standard defaults like ? and ! that would stand for 0..1 or 1..1. I looked around the documentation, but couldn't find any way to define this in the xText grammar. So far, I have a rule for the general case
Range: min=INT '..' max=INT;
However, I didn't find any way to define something like
Range: '?' min=0 max=1;
Range: '!' min=1 max=1;
How could I achieve similar behavior for my DSL?
Please note that I am not interested in generating a metamodel from the grammar, as the DSL models should adhere to an existing metamodel.
i dont know an easy solution for that but you might be able to customize Xtexts object creation e.g. like
Model: ranges+=AbstractRange*;
AbstractRange returns Range: ExplicitRange | ZORange | OORange;
ExplicitRange returns Range: min=INT ".." max=INT;
ZORange returns Range: {Range} max=ZEROONE;
ZEROONE returns ecore::EInt: "?";
OORange returns Range: {Range} max=ONEONE;
ONEONE returns ecore::EInt: "!";
And following Customizations
class MyDslEcoreElementFactory extends DefaultEcoreElementFactory {
#Inject extension MyDslGrammarAccess
override set(EObject object, String feature, Object value, String ruleName, INode node) throws ValueConverterException {
if (object instanceof Range) {
if (ruleName == grammar.name+"."+ZEROONERule.name) {
object.max = 1
object.min = 0
return;
} else if (ruleName == grammar.name+"."+ONEONERule.name) {
object.max = 1
object.min = 1
return;
}
}
super.set(object, feature, value, ruleName, node)
}
}
bound like this
class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
override bindIAstFactory() {
MyDslEcoreElementFactory
}
}
unfortunately org.eclipse.xtext.parser.IAstFactory.create(EClassifier)
does not have a second param that specifies the node or rule you are in and you resist to introduce subclasses for the ranges (in a metamodel inherited from your one) which would make this a bit easy (override create only)
Related
i have to create a domain class object which has a nullable attribute. This Creating is in an extansion of a primitive class.
For example: Domainclass
Meeting({required String id, required Datetime date, Example? example})
behind Example is an class like so: Example(String value)
MeetingPrimitive.dart:
extension MeetingPrimitiveX on Meeting {
Meeting toDomain() {
return Meeting(
id: id,
date: date,
example: example == null ? null : Example(example)
}
}
My question is, how can i simplify this:
example == null ? null : Example(example)
'''
thanks in advance
You generally can't.
You can change it in various ways, but nothing is more direct than what you have here.
One variant would be:
extension DoWith<T> on T {
R doWith<R>(R Function(T) action) => action(this);
}
With that, you can write:
example?.doWith(Example.new)
to conditionally call the Example.new constructor (tear-off of the unnamed constructor) if example is non-null.
Slightly shorter, requires a helper function, and ... isn't actually more readable IMO.
I am previously working with Netlogo and there are some very good built-in methods that allow me to filter and control the desired agents from the total population. (see: http://ccl.northwestern.edu/netlogo/docs/dictionary.html#agentsetgroup). For instance, I could very easily to command the different class of people agent in a simulation with simple codes like:
ask peoples with [wealth_type = "rich"] [donate money...]
ask peoples with [wealth_type = "poor"] [get money from rich people...]
In Repast, are there list of methods specifically built for easy controlling of agent set?
The equivalent in Repast Simphony Java is to use a Query. Queries apply a predicate to each agent in the Context and returns those that evaluate to true in an iterator. The PropertyEquals query evaluates an agent's property w/r to some value (e.g. "wealth_type" and "rich"). Note that "property" here refers to a Java property, i.e., a getter type method:
String getWealthType() {
return wealthType;
}
where "wealthType" is the name of the property.
As an example, in the JZombies example model, we can query Humans whose energy is equal to 5.
Query<Object> query = new PropertyEquals<Object>(context, "energy", 5);
for (Object o : query.query()) {
Human h = (Human)o;
System.out.println(h.getEnergy());
}
The query() iterator returns all the humans whose energy is equal to 5.
You can get a bit more complicated in the equivalence test by providing your own predicate. For example,
PropertyEqualsPredicate<Integer, Integer> pep = (a, b) -> {
return a * 2 == b;
};
Query<Object> query2 = new PropertyEquals<Object>(context, "energy", 8, pep);
for (Object o : query2.query()) {
Human h = (Human)o;
System.out.println(h.getEnergy());
}
Here, we are checking if the energy * 2 == 8. The predicate is passed the agent's property value in the first parameter and the value to compare against in the second parameter. Given that the predicate returns a boolean, you could also test for inequality, greater than etc.
Simphony has a variety of queries available. See,
https://repast.github.io/docs/api/repast_simphony/repast/simphony/query/package-summary.html
https://repast.github.io/docs/RepastReference/RepastReference.html#_repast_model_design_fundamental_concepts
for more info.
You can also do this in Simphony's ReLogo dialect:
ask (turtles()){
if (wealth_type == "rich") {
donateMoney()
}
if (wealth_type == "poor") {
getMoneyFromRichPeople()
}
}
If you want to just collect the richTurtles you can do (where "it" is the default method to access the individual turtle that is iterated over with findAll):
richTurtles = turtles().findAll{
it.wealth_type == "rich"
}
or with an explicit closure argument:
richTurtles = turtles().findAll{x->
x.wealth_type == "rich"
}
Does Dart support == and === ? What is the difference between equality and identity?
Dart supports == for equality and identical(a, b) for identity. Dart no longer supports the === syntax.
Use == for equality when you want to check if two objects are "equal". You can implement the == method in your class to define what equality means. For example:
class Person {
String ssn;
String name;
Person(this.ssn, this.name);
// Define that two persons are equal if their SSNs are equal
bool operator ==(other) {
return (other is Person && other.ssn == ssn);
}
}
main() {
var bob = Person('111', 'Bob');
var robert = Person('111', 'Robert');
print(bob == robert); // true
print(identical(bob, robert)); // false, because these are two different instances
}
Note that the semantics of a == b are:
If either a or b are null, return identical(a, b)
Otherwise, return a.==(b)
Use identical(a, b) to check if two variables reference the same instance. The identical function is a top-level function found in dart:core.
It should be noted that the use of the identical function in dart has some caveats as mentioned by this github issue comment:
The specification has been updated to treat identical between doubles
like this:
The identical() function is the predefined dart function that returns
true iff its two arguments are either:
The same object.
Of type int and have the same numeric value.
Of type double, are not NaNs, and have the same numeric value.
What this entails is that even though everything in dart is an object, and f and g are different objects, the following prints true.
int f = 99;
int g = 99;
print(identical(f, g));
because ints are identical by their value, not reference.
So to answer your question, == is used to identify if two objects have the same value, but the identical is used to test for referential equality except in the case of double and int as identified by the excerpt above.
See: equality-and-relational-operators
As DART is said to be related to javascript, where the === exists, I wish not be downvoted very quickly.
Identity as a concept means that 1 equals 1, but 1.0 doesn't equal 1, nor does false equal 0, nor does "2" equal 2, even though each one evaluates to each other and 1==1.0 returns true.
It should be noted that in Dart, identical works similarly to Javascript, where (5.0 == 5) is true, but identical(5.0, 5) is false.
I'm really brand new to Groovy and I'm trying to get something done. I've written some Groovy code (which works just fine) which receives some text. This text should be an integer (between 0 and 10). It may just happen a user enters something different. In that case I want to do some specific error handling.
Now I'm wondering, what's the best / grooviest way to test if a string-typed variable can be casted to an integer?
(what I want to do is either consume the integer in the string or set the outcome of my calculation to 0.
Thanks!
The String class has a isInteger() method you could use:
def toInteger (String input) {
if (input?.isInteger()) {
return input.toInteger()
}
return 0
}
use groovy contains
if ( x?.isInteger()) {
return (0..10).contains(x)
} else {
return false
}
Is this what you're saying?
Integer integer = 0
try {
integer = (Integer) string
assert integer > 0
assert integer < 10
catch(e) {
integer = 0
}
There are lots of ways this can be done in groovy, if you're comfortable with regular expressions, this is about as concise as you can get:
def processText(String text) {
text ==~ /(10|\d)/ ? text.toInteger() : 0
}
assert 0 == processText("-1")
(0..10).each {
assert it == processText("$it")
}
assert 0 == processText("11")
I'm a little unsure what you mean by "specific error handling" if the user does something different.
If this is a web application, I'd take a look at grails and the constraints that you can put on the fields of a domain object, that would let you easily express what you're trying to do.
You have the grails tag on your question, so if you are using Grails, you might consider making this an Integer property on a domain class. The param may come in as text, but you can bind it to an integer property with a default value of 0:
class MyDomain {
Integer whatever = 0
static constraints = {
whatever( min:0, max:10)
}
}
This question is about altering how the Grails data-binding handles string-to-integer conversion.
Consider the following domain object:
class Foo {
String name
Integer price
}
Furthermore, assume that the domain object is populated from HTTP request parameters:
def foo = new Foo(params).save()
The save() method above will fail if params.price == "" (empty string). I'd like to change this behaviour globally so that an empty string is parsed as zero (0) when converting from a string to an integer in Grails data-binding. How do I achieve that?
added a filter see the setion 5.5.1 Events and Auto Timestamping in the grails documentation (http://grails.org/doc/1.1.x/index.html)
def beforeInsert = {
if (price == '') { price = 0}
}
Instead of changing the data binding why not just write your own setter? In the setter test to see if the string is empty, if it is set price to 0. If it isn't do a normal integer conversion.
try this constraint instead
static constraints = {
price(validator: {val, obj ->
if (val == '' || val == 0) {
obj.price = 0
return true
} else if (val < 1) {
return false;
}
})
}
import org.grails.databinding.BindUsing
class Foo {
String name
#BindUsing({ obj, source ->
source["price"] ?: 0
})
Integer price
}