-
-
Notifications
You must be signed in to change notification settings - Fork 609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add hasAccess trait #18597
Labels
Comments
andrej.mitrovich (@AndrejMitrovic) commented on 2013-06-03T15:57:37Z@andralex: CC'ing you to get an idea if you like this enhancement proposal before I try implementing it (I'm eager to start hacking on it :) ). |
issues.dlang (@jmdavis) commented on 2013-06-03T16:09:56Z> Using is(typeof()) to check accessibility is a hacky workaround
Actually, according to Don (from what I recall in a discussion on unusable init values), I don't think that that necessarily even works. You may be forced to use __traits(compiles, foo) instead.
Regardless of that though, I'm not sure that it's really a hacky workaround. What if accessibility isn't the only problem? It seems to me that specifically checking for whether you have access is like checking file permissions before trying to read a file. Even if you have permissions, there are a host of other reasons that reading the file could fail, so checking for permissions explicitly doesn't generally buy you much - if anything. You only care why you can't read the file when you're trying to react differently for different error conditions, and I doubt that you generally care that you can't use a symbol due to access level as opposed to something else, so I would expect that checking for whether something compiles would be enough and might even save you having additional checks.
That doesn't mean that we shouldn't add something like this, but I question its general utility. |
andrej.mitrovich (@AndrejMitrovic) commented on 2013-06-03T16:12:28Z(In reply to comment #2)
> What if accessibility isn't the only problem?
That's exactly why we need this. is(typeof()) silences the problem altogether, meaning if your template fails for a reason *other* than accessibility problem, you won't know about it because is(typeof()) has silenced the error for you.
If on the other hand you check access, and you have access but then your template still fails, you will *know* why it failed since the compiler will tell you what went wrong, and then you can fix your template. |
andrei (@andralex) commented on 2013-06-09T17:38:07ZI'd say we should define a trait in std.traits, implement it with what we have, and defer the decision on a built-in trait. If needed it'll come up. |
k.hara.pg commented on 2013-07-19T11:11:13ZI think hasAccess traits would be completely redundant feature.
We can use __traits(compiles) + __traits(getMember).
module a;
struct S { int x; private int y; }
module b;
import a;
void getValues(T)(T t)
{
import std.stdio;
foreach (name; __traits(allMembers, T))
{
static if (__traits(compiles, __traits(getMember, t, name)))
writeln(name, ": ", mixin("t."~name));
}
}
void main()
{
S s;
getValues(s);
} |
issues.dlang (@jmdavis) commented on 2013-07-19T11:38:58ZIf what you really need to check is whether code has access to a particular symbol (as opposed to whether using it works), then it would be much more idiomatic if there were a trait for it rather than combining __traits(compiles, ...) with __traits(getMember, ...). So, from the standpoint of code clarity, a trait would be preferable. However, in most cases, I would think that it would be better to check whether using a symbol works rather than checking whether it's accessible, since that's generally what you care about. But if we have a strong enough use case for checking explicitly for access, then I think that it would be better to have trait for it because of what it gives you in code clarity. |
andrej.mitrovich (@AndrejMitrovic) commented on 2013-07-19T14:08:55Z(In reply to comment #5)
> I think hasAccess traits would be completely redundant feature.
This isn't a good workaround for two reasons:
1. It is not clear enough what is being done (same as JMD's argument)
2. __traits(compiles) silences all compiler errors.
#2 is the most important reason. Here's an example:
-----
struct S
{
int a;
}
void main()
{
static if (__traits(compiles, __traits(getMember, T, "a")))
{
pragma(msg, "Can access a!");
}
}
-----
This will not print anything, because the aggregate type is wrong (it doesn't even exist!). It should have been 'S', not 'T', but __traits(compiles) has gagged the error message.
Tracking down bugs like these are hard when there are no error messages. If instead we had a trait, the above would become:
-----
static if (__traits(hasAccess, __traits(getMember, T, "b")))
-----
And the error message is clear:
> Error: undefined identifier T, did you mean struct S? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Andrej Mitrovic (@AndrejMitrovic) reported this on 2013-06-03T15:53:20Z
Transferred from https://issues.dlang.org/show_bug.cgi?id=10258
CC List
Description
The text was updated successfully, but these errors were encountered: