Proposal: user defined attributes
Kapps
opantm2+spam at gmail.com
Fri Mar 16 17:41:17 PDT 2012
On Friday, 16 March 2012 at 16:09:55 UTC, Andrei Alexandrescu
wrote:
> So we have:
>
> class A {
> @note(Serializable.yes) int a;
> ...
> }
>
> vs. a hypothetical in-language solution:
>
> class A {
> int a;
> mixin(note("a", Serializable.yes));
> ...
> }
>
> I wonder to what extent the in-language solution can be made to
> work.
>
>
> Andrei
This gets to an unreasonable amount of noise and complexity.
First, you have the issue of using mixins. Using mixins is quite
ugly. It's very tool unfriendly. It's not easily readable. It can
mess up line numbers. It may or may not be limited in situations
such as with parameters.
In language solutions should be preferred for many things, but
ultimately, not everything is a nail to hammer.
Ultimately, I'd like to see being able to use any CTFE capable
struct/class for an attribute with a constructor, ideally with
access to the symbol it's defined on. This allows things like (if
my unchecked code was correct):
@attribute struct WebForm {
string FormName;
this(string FormName) {
this.FormName = FormName;
static assert(is(typeof(Symbol) : struct));
static assert(__traits(getAllMembers, Symbol).length > 0);
// TODO: Make sure at least one member set to
Browsable(true).
}
}
@attribute struct Validate {
string Pattern;
this(string Pattern) {
this.Pattern = Pattern;
static assert(isValidRegex(Pattern));
}
}
@WebForm("Account");
@PostTo("Services/CreateAccount")
@SecureOnly(true)
struct CreateAccountForm {
@Description("The name of your account. Must be between 3 and
12 letters.");
@Validate(r"\w{3,12}")
string Username;
@Validate(r"\w+@\w+.\w+");
@Description("The email address to associate with this
account.");
string Email;
}
While it's a bit of boiler plate to create the library and
attributes, you only need to do it once. Then you can make a very
nice form that automatically validates fields both clientside
(where JS and/or CSS3 is supported) and serverside (when posted
to Services/CreateAccount). You can verify a bunch of things at
compile-time, including that the service exists or that the
validation contains valid regex. And best of all, it's actually
readable unlike if you went with a mixin approach. You would end
up having 7 random mixins in that above form, and have to
manually check each one to see if it's creating code or just
creating an attribute. This way, you can see the @ and know it's
an attribute immediately.
Another thing that doesn't come up yet but may in the future:
reflection. It seems worrying to have random mixins adding
reflection info, as that's a job for the compiler. It knows about
when reflection is enabled, it knows how much it needs to
generate, if things exist after optimization, etc. There's no
point leaving that to a mixin and having to keep it in sync with
the compiler. This way though, there's no need. The reflection
data would just have an annotations property that can be accessed.
More information about the Digitalmars-d
mailing list