On 1/3/23 19:42, thebluepandabear wrote:
> @property {
As your post proves, that feature is at most half-baked and is
discouraged. Today, there is just one known obscure effect of using it.
> void name(string name) {
> _name = name;
> }
> d.name = "Poodle";
> In the code we can see that we have utilized UFCS (universal function
> call syntax)
UFCS is for calling free-standing functions as if they are member
functions. Since your example already uses member functions, this
feature is not UFCS. And I don't think it has a name.
It is always possible to pass a single-argument with the assignment syntax:
void foo(int i) {}
void main() {
foo = 42;
}
Pretty wild! :) But that's what makes your assignment above work. (Not
UFCS.)
> not enforced [...] we can
> do the following in our code:
> d.name("poodle");
I don't see a problem with that. :)
> I am disappointed that `@property` does not
Many people are disappointed that @property is pretty much useless.
> is there a way to enforce
D gives us the tools to do that but it's not trivial. The function can
return an object that represents a variable (member variable or not).
And an assignment to that representative object can set the actual variable.
However, I tried to achieve it with an intermediary object but failed
because the same ="Poodle" syntax broke it and demanded that we type the
empty parenthesis. So, I think what you want does not exist.
// I have a feeling something similar exists in Phobos
// but I could not find it.
//
// This is a reference to any variable.
struct MyRef(T) {
T * ptr;
void opAssign(T value) {
*ptr = value;
}
void toString(scope void delegate(in char[]) sink) const {
sink(*ptr);
}
}
// This is a convenience function template so that
// the users don't have to say e.g. MyRef!string
// themselves. (See name() below.)
auto myRef(T)(ref T var) {
return MyRef!T(&var);
}
class Dog {
@property name() {
return myRef(_name);
}
private {
string _name;
}
}
void main() {
Dog d = new Dog();
// Great: The following won't work.
// d.name("poodle");
// However, now there is the empty parenthesis. :(
d.name() = "Poodle";
import std.stdio;
writeln(d.name);
}
Ali