Templating Function Names

2016-12-08 Thread Bryce Kellogg via Digitalmars-d-learn
Say I've got a bunch of classes that inherit from a common 
interface (in this case Component) and a class Foo that can 
handle any subclass of Component. Like so:


interface Component { ... }
class A : Component { ... }
class B : Component { ... }
class C : Component { ... }

class Foo {
alias a = this.of!A;
alias b = this.of!B;
alias c = this.of!C;
void of(T : Component)(T t) { ... }
}

It's pretty trivial to access a specific component using regular 
templates:


f.of!A = new A();
f.of!B = new B();
f.of!C = new C();

And I can alias the instantiations of these templates as seen 
above for a cleaner interface:


f.a = new A();
f.b = new B();
f.c = new C();

However, suppose I have the following situation:

void main() {
Foo f = new Foo();
class D : Component { ... }

f.of!D = new D(); // works fine
f.d = new D();// fails to compile (for obvious reason)
}

Is there a way I can get a function of Foo named after D (like 
f.d() or f.D()) without knowing before hand every single subclass 
of Component and adding aliases manually?


For example, is there a way to template the name of the function 
or an alias like:


void T(T : Component)(T t) { ... }
or
alias T = this.of!T;

Both of these just gave me functions named T.

The important thing is that it's transparent to the person 
creating a new subclass of Component. It should look like Foo 
always had a property named after their custom Component.


Is this possible?

Thanks!
Bryce



ModuleInfo linker error when importing std.stdio and using package.d

2016-11-08 Thread Bryce Kellogg via Digitalmars-d-learn
Hi everyone, I'm new to D, and I'm trying to get a handle on the 
correct way to use packages, modules, and importing things. I 
created a simple example, but I'm getting linker errors in weird 
situations. I'm hoping to get some insight into why the error is 
happening and best practices in these sorts of situations.


I've got a simple project set up as follows:
.
├── dub.json
└── source/
├── app.d
└── my_package/
├── my_module.d
└── package.d


The contents of dub.json are pretty simple:


{
"name": "my_package_test",
"description": "A minimal D application.",
"copyright": "Copyright © 2016, kellogg",
"authors": ["kellogg"],
"dependencies": {
}
}


In app.d, all I do is import my package and instantiate my class.

import my_package;
void main() {
my_module m = new my_module();
}


And here's my_module.d

module my_package.my_module;
import std.stdio;
class my_module {
this() {
writeln("Hello World!");
}
}



Finally, a one line package.d:

public import my_package.my_module;


Building this via dub results in the error:

.dub/obj/app.o:(.data._D3app12__ModuleInfoZ[_D3app12__ModuleInfoZ]+0x10): 
undefined reference to `_D10my_package12__ModuleInfoZ'
collect2: error: ld returned 1 exit status
Error: /usr/bin/gcc failed with status: 1
ldc2 failed with exit code 1.


Interestingly, if I remove the 'import std.stdio;' and writeln() 
from my_module.d, it compiles fine. It also works if I move the 
import down to inside the constructor, or replace the import in 
app.d with 'import my_package.my_module;' (side stepping the 
package.d).



To summarize: importing my package via package.d results in a 
linker error if I import std.stdio at the top level in my module. 
I'm wondering: what does this error mean, what does it have to do 
with std.stdio, and am I even using package.d correctly?


Thanks!