www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Accessing class with module name as Java's

reply "tcak" <tcak gmail.com> writes:
In java, if I create a file, the class that is defined in it must 
have the same name of file. So, with the file name, I can relate 
to class directly. Is there any way to achieve this in D?

One way I achieved it, though I cannot put namespace on it.


file: project.d
==================
module project;

class project{}


file: main.d
==================

import project: project;

auto p = new project();


When I do this, it works, but I cannot make it work with 
namespace unfortunately.

Any simple (complexity isn't desired please) way to do this?

My only though without breaking anything in the language is to 
relate a struct or class to module itself to do this, but it 
might require a new keyword.
Jan 12 2015
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
tcak:

 One way I achieved it, though I cannot put namespace on it.


 file: project.d
 ==================
 module project;

 class project{}
D modules can contain lot of stuff, like variables, constants, enums, types, structs, etc. And you usually put more than one class in each D module. Also D class names should be capitalized (like "Project").
 When I do this, it works, but I cannot make it work with 
 namespace unfortunately.
What namespace? D has modules, unlike C++. In general it's a bad idea to have inside a module a name (like a variable name or struct name) equal to the module name, because it causes confusion. Please show what doesn't work. Bye, bearophile
Jan 12 2015
next sibling parent "tcak" <tcak gmail.com> writes:
On Monday, 12 January 2015 at 18:11:35 UTC, bearophile wrote:
 D modules can contain lot of stuff, like variables, constants, 
 enums, types, structs, etc. And you usually put more than one 
 class in each D module. Also D class names should be 
 capitalized (like "Project").


 When I do this, it works, but I cannot make it work with 
 namespace unfortunately.
What namespace? D has modules, unlike C++. In general it's a bad idea to have inside a module a name (like a variable name or struct name) equal to the module name, because it causes confusion. Please show what doesn't work. Bye, bearophile
With namespace, I mean like "core.sync.mutex", not just "mutex". As you will find lots of examples in even in Phobos, there are so many name duplications. Example: core.sync.mutex.Mutex, core.thread.Thread Like it or don't, it is ugly. And I am sure, those modules are designed in that way, because of not being able to what I am asking about. Because D can contain many things doesn't mean it is any better, I am using it for many years already.
Jan 12 2015
prev sibling parent reply "tcak" <tcak gmail.com> writes:
 What namespace? D has modules, unlike C++. In general it's a 
 bad idea to have inside a module a name (like a variable name 
 or struct name) equal to the module name, because it causes 
 confusion.
I am confused as well. core.stdc.errno property int errno() { return getErrno(); } property int errno(int n) { return setErrno(n); }
Jan 12 2015
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 01/12/2015 08:22 PM, tcak wrote:
 What namespace? D has modules, unlike C++. In general it's a bad idea
 to have inside a module a name (like a variable name or struct name)
 equal to the module name, because it causes confusion.
I am confused as well. core.stdc.errno property int errno() { return getErrno(); } property int errno(int n) { return setErrno(n); }
errno better worked similar to what it represents ("the" errno) so I am not surprised that it has the same name as its module. It is like how errno.h defines errno in C. Like bearophile though, I don't understand the namespace issue. Can you explain it with a piece of code please. Ali
Jan 12 2015
parent reply "tcak" <tcak gmail.com> writes:
On Tuesday, 13 January 2015 at 05:18:46 UTC, Ali Çehreli wrote:
 On 01/12/2015 08:22 PM, tcak wrote:
 What namespace? D has modules, unlike C++. In general it's a
bad idea
 to have inside a module a name (like a variable name or
struct name)
 equal to the module name, because it causes confusion.
I am confused as well. core.stdc.errno property int errno() { return getErrno(); } property int errno(int n) { return setErrno(n); }
errno better worked similar to what it represents ("the" errno) so I am not surprised that it has the same name as its module. It is like how errno.h defines errno in C. Like bearophile though, I don't understand the namespace issue. Can you explain it with a piece of code please. Ali
Right now I am building a web server. Some of class names those are defined in main program are as follows: HttpSocketConnectionRequest HttpSocketConnection HttpSocketListenerEvents These are all in main.d. Now, because the length of codes of these classes are long, I need to put them into separate files to manage them easily. Look what I need to do: I will create a file called "request.d", and then put "HttpSocketConnectionRequest" into it. Then create "connection.d", and then put "HttpSocketConnection" into. It is just making everything dirty. request.HttpSocketConnectionRequest connection.HttpSocketConnection I just want to create a file called "HttpSocketConnectionRequest.d", and put "HttpSocketConnectionRequest" into it. This is how it works in Java. So, you do not repeat the names again and again. (I have given an example in previous posts in this thread.) I thought maybe I could achieve this by just using what the language provides by doing that: import HttpSocketConnectionRequest: HttpSocketConnectionRequest; First one is module name, second one is the name of class that is defined in it. This way, I do not have to repeat the names, and codes are much cleaner. But when the project gets complex, I will need to add sub names (what I meant with namespace) like: HttpSocketConnectionRequest.d ============== module net.http.HttpSocketConnectionRequest; class HttpSocketConnectionRequest{} With this, above solution doesn't work unfortunately. You cannot do that with that solution: auto req = new net.http.HttpSocketConnectionRequest(); Because it requires module name still. You still have to do: auto req = new net.http.HttpSocketConnectionRequest.HttpSocketConnectionRequest(); Which has name repeatition again, and as "many" people would agree, doesn't seem like any good design at all. So, I am looking for a nice solution in the language. My idea was to bind a class or struct to a module. Like: module class HttpSocketConnectionRequest{} (This is just an example) Yes, this would prevent accessing content outside of that class in the module, but if you have more things already, programmer wouldn't be using binding in the first place as well. It doesn't affect language at all, and makes the statements much more cleaner. Even Phobos can take advantage of this.
Jan 12 2015
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 01/12/2015 10:09 PM, tcak wrote:

 It is just making everything dirty.
 request.HttpSocketConnectionRequest
 connection.HttpSocketConnection
You can name the files the same as their classes: HttpSocketConnectionRequest.d, etc.
 I just want to create a file called "HttpSocketConnectionRequest.d", and
 put "HttpSocketConnectionRequest" into it.
I have a feeling I still don't understand the question because I've just tried it and it works the same in D. (Edit: Yes, it works the same but I finally understood the question below.)
 import HttpSocketConnectionRequest: HttpSocketConnectionRequest;
Ok, that works.
 HttpSocketConnectionRequest.d
 ==============
 module net.http.HttpSocketConnectionRequest;
So, you create the directory hierarchy net/http and put HttpSocketConnectionRequest.d in it. Ok.
 class HttpSocketConnectionRequest{}


 With this, above solution doesn't work unfortunately. You cannot do that
 with that solution:

 auto req = new net.http.HttpSocketConnectionRequest();
Oh! Finally I see what you mean. So, this alreday works: auto h = new net .http .HttpSocketConnectionRequest .HttpSocketConnectionRequest(); but you want this to work: auto h = new net .http .HttpSocketConnectionRequest(); (If so, why didn't say so? :) ) And you get the following error: Error: module net.http.HttpSocketConnectionRequest is used as a type Yeah, net.http.HttpSocketConnectionRequest is a module. :-/ I don't know a solution to this problem. Ali
Jan 12 2015
prev sibling parent reply "Colin" <grogan.colin gmail.com> writes:
Have the following directory structure?

~/testModule$ find . -print
.
./net
./net/http_.d    # **
./net/http
./net/http/Mod1.d
./net/http/Mod2.d
./main.d

** I put the _ here to make it seperate from the net/http
directory. Probably, a better solution exists, this was hacked 
together quickly :)

In http_.d have:
module net.http_;  // again, a better solution surely exists
public import net.http.Mod1;
public import net.http.Mod2;

Then in your main have
import net.http_;

You can then use whatever's in Mod1 and Mod2 modules.
In your case, Mod1/Mod2 will be like
HTTPConnectionRequest/HTTPConnectionResponse and will only
contain a single class. This works for me.

You can also go a little further and have renamed imports.
Something like:
public import Renamed = net.http.Mod2;

Then in main.d call it with:
Renamed.Mod2 mod2 = new renamed.Mod2;

Feels just like Java :)
Jan 13 2015
parent reply "Colin" <grogan.colin gmail.com> writes:
On Tuesday, 13 January 2015 at 09:22:04 UTC, Colin wrote:
 Have the following directory structure?

 ~/testModule$ find . -print
 .
 ./net
 ./net/http_.d    # **
 ./net/http
 ./net/http/Mod1.d
 ./net/http/Mod2.d
 ./main.d

 ** I put the _ here to make it seperate from the net/http
 directory. Probably, a better solution exists, this was hacked 
 together quickly :)

 In http_.d have:
 module net.http_;  // again, a better solution surely exists
 public import net.http.Mod1;
 public import net.http.Mod2;

 Then in your main have
 import net.http_;

 You can then use whatever's in Mod1 and Mod2 modules.
 In your case, Mod1/Mod2 will be like
 HTTPConnectionRequest/HTTPConnectionResponse and will only
 contain a single class. This works for me.

 You can also go a little further and have renamed imports.
 Something like:
 public import Renamed = net.http.Mod2;

 Then in main.d call it with:
 Renamed.Mod2 mod2 = new renamed.Mod2;

 Feels just like Java :)
Ah, I just re-read your OP. Your already at this point :)
Jan 13 2015
parent reply "tcak" <tcak gmail.com> writes:
 Ah, I just re-read your OP. Your already at this point :)
Since everybody has understood the problem, and nobody could have come up with a solution yet, my idea is that: HttpSocketConnectionRequest.d ===================================== module net.http.HttpSocketConnectionRequest; module class HttpSocketConnectionRequest{} If compiler allowed "module" keyword to be used as an attribute for ONLY ONE class or struct definition in the module as above, module's name could be used as you were to be pointing to class directly. This would let us (and Phobos developers) to be able to separate code files into multiple files much easily, and solve my problem as well :).
Jan 13 2015
parent Daniel =?UTF-8?B?S296w6Fr?= via Digitalmars-d-learn writes:
V Tue, 13 Jan 2015 10:58:27 +0000
tcak via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
napsáno:

 Ah, I just re-read your OP. Your already at this point :)
Since everybody has understood the problem, and nobody could have come up with a solution yet, my idea is that: HttpSocketConnectionRequest.d ===================================== module net.http.HttpSocketConnectionRequest; module class HttpSocketConnectionRequest{} If compiler allowed "module" keyword to be used as an attribute for ONLY ONE class or struct definition in the module as above, module's name could be used as you were to be pointing to class directly. This would let us (and Phobos developers) to be able to separate code files into multiple files much easily, and solve my problem as well :).
There is a way around: -- main.d -- import std.stdio; import net.http; void main(string[] arg) { auto p = new net.http.HttpSocketConnectionRequest(); } -- net/http/package.d -- module net.http; private import net.http.http_socket_connection_request; -- net/http/http_socket_connection_request.d -- module net.http.http_socket_connection_request; class HttpSocketConnectionRequest { } or -- main.d -- import std.stdio; static import net.http; void main(string[] arg) { auto p = new net.http.HttpSocketConnectionRequest(); } -- net/http/package.d -- module net.http; import net.http.http_socket_connection_request; -- net/http/http_socket_connection_request.d -- module net.http.http_socket_connection_request; class HttpSocketConnectionRequest { }
Jan 13 2015