digitalmars.D.learn - private module stuff
- Sean Cavanaugh (27/27) May 08 2011 So I was learning how to make a module of mine very strict with private...
- bearophile (4/9) May 08 2011 You are expecting the right thing. If you are right, then it's a bug tha...
- Jonathan M Davis (9/20) May 08 2011 They're private _access_ but still visible. I believe that that is the c...
- bearophile (9/13) May 08 2011 Do you mean something like this? This returns a struct defined inside, b...
- Jonathan M Davis (8/23) May 08 2011 I believe that C++, C#, and Java all treat private as a matter of access...
- Sean Cavanaugh (39/59) May 08 2011 The more I play with private/protected/package the more confused I am by...
- bearophile (4/7) May 08 2011 It's an implementation bug or a design bug. If it's not already in Bugzi...
- Jonathan M Davis (40/124) May 08 2011 private, public, protected, and private are _always_ about access and _n...
So I was learning how to make a module of mine very strict with private parts, and was surprised I could only do this with global variables and functions. Enums, structs, and classes are fully visible outside the module regardless of being wrapped in a private{} or prefixed with private. Am I expecting too much here? rough code: module mymoduletree.mymodule; private { struct foo { int x; int y; } int somevar = 4; } ..... module someothertree.othermodule; import mymoduletree.mymodule; int bar(int arg) { foo var; // why can i use this type here?? var.x = arg; var.y = somevar; // this generates an error (access of somevar is private and not allowed) return var.y; }
May 08 2011
Sean Cavanaugh:So I was learning how to make a module of mine very strict with private parts, and was surprised I could only do this with global variables and functions. Enums, structs, and classes are fully visible outside the module regardless of being wrapped in a private{} or prefixed with private. Am I expecting too much here?You are expecting the right thing. If you are right, then it's a bug that eventually needs to be fixed. Take a look in Bugzilla, there are several already reported import/module-related bugs. Bye, bearophile
May 08 2011
Sean Cavanaugh:They're private _access_ but still visible. I believe that that is the correct behavior and not a bug at all. I believe that it's necessary for stuff like where various functions in std.algorithm return auto and return a private struct which you cannot construct yourself. Code which uses that struct needs to know about it so that it can use it properly, but since it's private, it can't declare it directly. It works because the types are appropriately generic (ranges in this case). Regardless, I believe that the current behavior with private is intended. - Jonathan M DavisSo I was learning how to make a module of mine very strict with private parts, and was surprised I could only do this with global variables and functions. Enums, structs, and classes are fully visible outside the module regardless of being wrapped in a private{} or prefixed with private. Am I expecting too much here?You are expecting the right thing. If you are right, then it's a bug that eventually needs to be fixed. Take a look in Bugzilla, there are several already reported import/module-related bugs.
May 08 2011
Jonathan M Davis:They're private _access_ but still visible.In my opinion this is not good, it looks like a messy special case.I believe that it's necessary for stuff like where various functions in std.algorithm return auto and return a private struct which you cannot construct yourself.Do you mean something like this? This returns a struct defined inside, but it's not a private definition. auto foo() { struct Bar {} return Bar(); } Bye, bearophile
May 08 2011
Jonathan M Davis:visibility, though in most cases, there's no real difference in usage. So, there's nothing abnormal - quite the opposite really - with D doing what it's doing.They're private _access_ but still visible.In my opinion this is not good, it looks like a messy special case.I believe that it's necessary for stuff like where various functions in std.algorithm return auto and return a private struct which you cannot construct yourself.Do you mean something like this? This returns a struct defined inside, but it's not a private definition. auto foo() { struct Bar {} return Bar(); }True. That wasn't the best example, since that's not techinically private, but you can run into the same situation with classes or structs which _are_ private. - Jonathan M Davis
May 08 2011
On 5/8/2011 4:05 AM, Jonathan M Davis wrote:The more I play with private/protected/package the more confused I am by it. For the most part the rules are: Functions and variables have protection Types (enum, struct, class) do not this and ~this are special and are not considered functions, and are always public struct and class members always default to public If you search phobos you will find occurences of 'private struct' and 'private class', so even the people writing libraries are expecting something to be happening that isn't. For example: //in std.parallelism: private struct AbstractTask { mixin BaseMixin!(TaskStatus.notStarted); void job() { runTask(&this); } } //and in std.demangle: private class MangleException : Exception { this() { super("MangleException"); } } and in my code I can compile the following without compile-time errors: import std.parallelism; import std.demangle; int main() { MangleException bar = new MangleException(); AbstractTask foo; foo.job(); return 0; } With the language the way it is now, it is nonsensical to have the attributes public/protected/package/private/export precede the keyword struct, class, or enum.Sean Cavanaugh:They're private _access_ but still visible. I believe that that is the correct behavior and not a bug at all. I believe that it's necessary for stuff like where various functions in std.algorithm return auto and return a private struct which you cannot construct yourself. Code which uses that struct needs to know about it so that it can use it properly, but since it's private, it can't declare it directly. It works because the types are appropriately generic (ranges in this case). Regardless, I believe that the current behavior with private is intended. - Jonathan M DavisSo I was learning how to make a module of mine very strict with private parts, and was surprised I could only do this with global variables and functions. Enums, structs, and classes are fully visible outside the module regardless of being wrapped in a private{} or prefixed with private. Am I expecting too much here?You are expecting the right thing. If you are right, then it's a bug that eventually needs to be fixed. Take a look in Bugzilla, there are several already reported import/module-related bugs.
May 08 2011
Sean Cavanaugh:With the language the way it is now, it is nonsensical to have the attributes public/protected/package/private/export precede the keyword struct, class, or enum.It's an implementation bug or a design bug. If it's not already in Bugzilla then it deserves to be there. Bye, bearophile
May 08 2011
On 5/8/2011 4:05 AM, Jonathan M Davis wrote:private, public, protected, and private are _always_ about access and _never_ about visibility. They affect whether you can _use_ a particular symbol in a particular piece of code, _not_ whether the compiler can see it in that context. It doesn't matter whether it's a function, variable, class, etc. Now, there may be bugs in the current implementation, but the design is fairly straightforward. For instance, anything templated is currently always public regardless of what you mark it as ( http://d.puremagic.com/issues/show_bug.cgi?id=1904 , http://d.puremagic.com/issues/show_bug.cgi?id=2775 ). Also, it looks like there is a bug report for structs and classes not dealing with private properly ( http://d.puremagic.com/issues/show_bug.cgi?id=2830 ) when the entire class or struct is marked as private. So unfortunately, the implementation _is_ currently buggy, but the design is fairly straightforward. Oh, and this and ~this _are_ functions (albeit special) and can be made private - or even outright removed entirely with disable. Traits works with __ctor and __dtor rather than this and ~this, and you can call the constructor with __ctor (though it's unlikely that there's a case where you should) and the destructor with __dtor (though there probably isn't really a valid case to do that - use clear instead, and it'll call the destructor along with everything else it does). The thing with the default constructor is that it exists if you don't declare any constructors, and it'll default to public, so you generally have to declare it and make it private if you want it to have a default constructor and not have it public. That _does_ seem like a likely place for a bug in the case where the class is private, but since that's completely broken right now anyway, that's not really a concern. The destructor is in the same boat, though why you'd want to make the destructor private, I don't know. And structs don't have the issue with default constructors because they can't have them. So, yes, the current implementation is broken (and more broken than I thought that it was actually), but the basic design is quite straightforward. I would think that assuming that dmd were not buggy with regards to private that the access specifiers would generally work as you expect them to - though there may be some cases where they would surprise you. For instance, per TDPL, private member functions are overridable but not callable (as they wolud be in C++) by derived classes, which surprises a lot of people in C++ (though presently, private functions are not overridable - there's at least one bug report on it - so this surprising issue doesn't come up right now). And it's because access specifiers are for _access_ only, not visibility. - Jonathan M DavisThe more I play with private/protected/package the more confused I am by it. For the most part the rules are: Functions and variables have protection Types (enum, struct, class) do not this and ~this are special and are not considered functions, and are always public struct and class members always default to public If you search phobos you will find occurences of 'private struct' and 'private class', so even the people writing libraries are expecting something to be happening that isn't. For example: //in std.parallelism: private struct AbstractTask { mixin BaseMixin!(TaskStatus.notStarted); void job() { runTask(&this); } } //and in std.demangle: private class MangleException : Exception { this() { super("MangleException"); } } and in my code I can compile the following without compile-time errors: import std.parallelism; import std.demangle; int main() { MangleException bar = new MangleException(); AbstractTask foo; foo.job(); return 0; } With the language the way it is now, it is nonsensical to have the attributes public/protected/package/private/export precede the keyword struct, class, or enum.Sean Cavanaugh:They're private _access_ but still visible. I believe that that is the correct behavior and not a bug at all. I believe that it's necessary for stuff like where various functions in std.algorithm return auto and return a private struct which you cannot construct yourself. Code which uses that struct needs to know about it so that it can use it properly, but since it's private, it can't declare it directly. It works because the types are appropriately generic (ranges in this case). Regardless, I believe that the current behavior with private is intended. - Jonathan M DavisSo I was learning how to make a module of mine very strict with private parts, and was surprised I could only do this with global variables and functions. Enums, structs, and classes are fully visible outside the module regardless of being wrapped in a private{} or prefixed with private. Am I expecting too much here?You are expecting the right thing. If you are right, then it's a bug that eventually needs to be fixed. Take a look in Bugzilla, there are several already reported import/module-related bugs.
May 08 2011