This one has been bothering me for a while.
It seems like it's impossible to use the with-method in a trait.
Example:
class P {
int prop
}
trait T {
P pogo = new P().with {
prop = 42 // MissingPropertyException: No such property: prop for class: C
return it
}
}
class C implements T {
}
def pogo = new C().pogo
assert pogo.prop == 42
Can anyone explain why that is?
The code is borrowed from this old thing.
(Comment, but need answer formatting.)
It needs to be it.prop = 42, although I don't recall why.
Maybe because C hasn't been fully constructed yet? It's been awhile.
trait T {
P pogo = new P().with {
it.prop = 42
return it
}
}
def pogo = new C().pogo
println(pogo.prop)
assert pogo.prop == 42
def c = new C()
c.pogo.prop = 12
assert c.pogo.prop == 12
Related
I have a situation like this:
TestClass = { param = { n = 5 } }
function TestClass:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function TestClass:update(n)
n = n or 1
self.param.n = self.param.n + n
end
The issue is that when I instantiate an object like: obj = TestClass:new() the update method doesn't update the value stored in the obj table but instead it changes the value inside the default table: TestClass
Is there a way to fix this? I already looked up the tutorial by the creators of lua but they say nothing about tables as attributes.
I think you should do it like this then:
function TestClass:new(o)
o = o or { param = { n = 5 } }
setmetatable(o, self)
self.__index = self
return o
end
I solved this and the problem was that tables are stored by reference, not value so the solution was to create the table inside the o object at the time of instancing (the TestClass:new() method).
To do this automatically and only for params that are not passed in I wrote this little function:
function setDefaults(o, def)
for k,v in pairs(def) do
o[k] = o[k] or v
end
end
And it is simply used like this:
function TestClass:new(o)
o = o or {}
setDefaults(o, {
param = { n = 5 }
})
setmetatable(o, self)
self.__index = self
return o
end
I also wanted to thank a lot u/JackMacWindowsLinux and Ivo Beckers for helping me find this solution.
I want to clear all elements within a Skip list, like this:
Module mod = current()
Skip skip = create()
put(skip, 1, "test")
put(skip, 2, mod)
clearSkip(skip) // Removes all elements
example script for deleting Skips of custom types, here: type OutLinkInfo:
struct OutLinkInfo {}
OutLinkInfo createOutLinkInfo_() { DxlObject d = new(); OutLinkInfo x = (addr_ d) OutLinkInfo; return(x) }
DxlObject DxlObjectOf(OutLinkInfo x) { return((addr_ x) DxlObject) }
void deleteOutLinkInfo(OutLinkInfo &x) { DxlObject d = DxlObjectOf(x); delete(d); x = null; return() }
Skip deleteOutLinkInfo(Skip sk)
{
OutLinkInfo x = null OutLinkInfo
for x in sk do { deleteOutLinkInfo(x) }
delete(sk); sk = null
return(sk)
}
You can use the setempty(Skip) function, although this specific overload is undocumented as far as I know.
Let's say i have code like this :
class A{ foo() => "A";}
class B{ foo() => "B";}
class C{ foo() => "C";}
class Mix extends A with B,C {
foo() => "MIX";
bar() => super.foo();
}
class MessABC = Object with A,B,C;
class MessBCA = Object with B,C,A;
class MessCAB = Object with C,A,B;
void main() {
Mix mix = new Mix();
MessABC mABC = new MessABC();
MessBCA mBCA = new MessBCA();
MessCAB mCAB = new MessCAB();
print("Mix.foo = ${mix.foo()} Mix.bar = ${mix.bar()} \n"
"mABC.foo = ${mABC.foo()} \n"
"mBCA.foo = ${mBCA.foo()} \n"
"mCAB.foo = ${mCAB.foo()} \n");
}
The output
Mix.foo = MIX Mix.bar = C
mABC.foo = C
mBCA.foo = A
mCAB.foo = B
On the mix object I can call both Mix.foo and C.foo with the super (actually i expected A.foo)
But can i somehow call A.foo and B.foo ?
Also i am a bit confused by the with semantics. A,B,C Looks like "one rank enumeration" but the order is important. And "Dart Editor" doesn't warn me about the name collision. Perhaps i can enable this warning?
To me it feels like something that makes you confused and error-prone.
Mixin application is processed from left to right.
The superclass of Object with A,B,C is Object with A,B, which again has the superclasses Object with A and then Object.
The overriding rules for mixins are the same as for non-mixin superclasses. Your C.foo in Mix overrides the ones inherited from A and B, so Mix.bar's super.foo() only reaches the C.foo, and there is no way to access A.foo or B.foo.
Overriding is perfectly ok, and doesn't cause any warnings, as long as the methods have compatible signatures.
The most thorough description of mixins is still https://www.dartlang.org/articles/mixins/
I want to overload the the comparison operator (==) in Dart to compare structures. Now I'm not sure how to do this for derived classes when I already have overloaded the comparison operator of the base class and want to reuse that.
Assuming I have a a base class like:
class Base
{
int _a;
String _b;
bool operator ==(Base other)
{
if (identical(other, this)) return true;
if (_a != other._a) return false;
if (_b != other._b) return false;
return true;
}
}
Then I declare I derived class that adds additional fields and also want to overload operator==. I only want to compare the additional fields in the derived class and delegate the comparison of Base fields to the Base class. In other programming languages I could do something like Base::operator==(other) or super.equals(other), but in Dart I can't figure out what's the best way to do it.
class Derived extends Base
{
int _c; // additional field
bool operator ==(Derived other)
{
if (identical(other, this)) return true;
if (_c != other._c) return false; // Comparison of new field
// The following approach gives the compiler error:
// Equality expression cannot be operand of another equality expression.
if (!(super.==(other))) return false;
// The following produces "Unnecessary cast" warnings
// It also only recursively calls the Derived operator
if ((this as Base) != (other as Base)) return false;
return true;
}
}
I guess what I could do is:
Compare all fields of base class also in the derived class: Is very error prone if base class get's changed and also doesn't work when base and derived are in different packages.
Declare an equals function with the same logic as currently operator == in it, call super.equals() to compare the base class and delegate all calls of operator== to the equals function. However it doesn't look too appealing to implement equals and operator ==.
So what's the best or recommended solution for this problem?
Ok, after some further experiments I figured it out on my own.
It's simply calling:
super==(other)
I tried it with super.operator==(other) and super.==(other) before, but didn't expect that the simple super==(other) is sufficient.
For the given example above the correct operator is:
bool operator ==(Derived other)
{
if (identical(other, this)) return true;
if (_c != other._c) return false;
if (!(super==(other))) return false;
return true;
}
Seems I am bumping a 5 year old question, but since now we have Dart 2...
the == operator can easily be defined inline.
class Base {
int a;
String b;
bool operator ==(other) => other is Base
&& other.a == a
&& other.b == b;
}
To reuse from a derived class, super == other still seems to be the way.
class Derived extends Base {
int c;
bool operator ==(other) => other is Derived
&& super == other
&& other.c == c;
}
Now this being said I discovered a major gotcha, the == operator that is called seems to be that of the left side of the comparision. That is Base == Derived will call Base's == comparision, while Derived == Base will call call Derived's == comparison (and subsequently Base's). This does seem reasonable, but had me scratching my head for a minute.
Ex:
main() {
Base b = new Base();
Derived d1 = new Derived();
Derived d2 = new Derived();
b.a = 6;
d1.a = 6;
d2.a = 6;
b.b = "Hi";
d1.b = "Hi";
d2.b = "Hi";
d1.c = 1;
d2.c = 1;
assert(d1 == d2); // pass
assert(b == d1); // PASS!!!
assert(d1 == b); // fail
}
(Note: I removed the private _'s from the fields for demonstration purposes.)
To avoid the issue where a base class incorrectly has equality with a child clase you can add the additional check for runtimeType as follows.
bool operator ==(other) => other is Base
&& this.runtimeType == other.runtimeType
&& other.a == a
&& other.b == b;
i am trying to set final properties in Groovy source (used in a Grails project) and following some examples but somehow i does not seem to work and i cannot find out why..
class Foo {
final x
Foo(Map m=[:]) {
m.each { key, value -> this.#"$key" = value }
}
}
def foo = new Foo(x:1)
I am getting the error:
Cannot set the property 'x' because the backing field is final.
According to some posts found on the internet this should work.
Why does fail how can is set the properties via a map when using a final field?
You can achieve the result you seek by using the #Immutable annotation
#Immutable
class Foo {
def x
}
Then this can be called as
def foo = new Foo([:])
or
def foo = new Foo(x:42)
and then later
foo.x = 43
causes
ERROR groovy.lang.ReadOnlyPropertyException:
Cannot set readonly property: y for class: Foo
I don't know why your constructor with a Map argument doesn't work, but this constructor does:
class Foo {
final x
Foo(x) {
this.x = x
}
}
def foo = new Foo(1)
I think, You should use #MapConstructor annotation
#ToString(includePackage = false, includeNames = true)
#MapConstructor
class A {
#Final
String x
int y
}
def a = new A(x: 'david', y: 12)
println "a = $a"