digitalmars.D.learn - Class parameters that are either setable at run-time or compile-time
- Markus Mayr (45/45) Aug 10 2014 Hello,
- Rikki Cattermole (7/48) Aug 10 2014 Unless you need to change the defaults of the values being passed in,
- Martijn Pot (11/58) Aug 10 2014 A couple of words (search terms) pop up in my mind:
Hello, I am new to D. I am sorry if this question was already answered or if it is trivial. I am having a class. That class takes several parameters that may be known at either compile time or run time. I want users of my class to be able to pass the parameters either as template parameters to the class or to the constructor of that class. At the moment, I have got the following code: class X(int a = some_dummy_value, int b = some_dummy_value) { static if (a == some_dummy_value) static immutable int a_ = a; else immutable int a_; // etc. this(int a = some_dummy_value, int b = some_dummy_value) { static if (a != some_dummy_value) this.a_ = a; static if (b != some_dummy_value) this.b_ = b; } }; This works, as far as I can tell. But there is one problem: users may forget to provide the value at compile time and run time. In that case, the members a_, b_ end up with some_dummy_values. Of course, I can notify the user at run time about this misbehaviour, but I would prefer to tell them at compile time. The only solution I am aware of is to use static if in order to provide one of four constructors depending on the compile time values of a, b, i.e. * none provided at compile time, * a provided at compile time, * b provided at compile time, * both provided at compile time. This is perfectly fine for one or two arguments, but I have gotten three of them (i.e. 8 constructors) and may want to add more later on. Since the number of constructors scales exponentially with the number of parameters, I have a feeling that this approach won't scale well. Is there any elegant solution to the problem? By the way, this is why I am doing this: Depending on the values of a and b, the class chooses how to implement some parts of its interface; if a or b are not provided, it may choose generic but slow fall back implementations. If there is any other solution to that problem, I also would like to know. Thanks a lot and I hope this is how this mailing list works! Best regards, Markus Mayr
Aug 10 2014
On 10/08/2014 10:47 p.m., Markus Mayr wrote:Hello, I am new to D. I am sorry if this question was already answered or if it is trivial. I am having a class. That class takes several parameters that may be known at either compile time or run time. I want users of my class to be able to pass the parameters either as template parameters to the class or to the constructor of that class. At the moment, I have got the following code: class X(int a = some_dummy_value, int b = some_dummy_value) { static if (a == some_dummy_value) static immutable int a_ = a; else immutable int a_; // etc. this(int a = some_dummy_value, int b = some_dummy_value) { static if (a != some_dummy_value) this.a_ = a; static if (b != some_dummy_value) this.b_ = b; } }; This works, as far as I can tell. But there is one problem: users may forget to provide the value at compile time and run time. In that case, the members a_, b_ end up with some_dummy_values. Of course, I can notify the user at run time about this misbehaviour, but I would prefer to tell them at compile time. The only solution I am aware of is to use static if in order to provide one of four constructors depending on the compile time values of a, b, i.e. * none provided at compile time, * a provided at compile time, * b provided at compile time, * both provided at compile time. This is perfectly fine for one or two arguments, but I have gotten three of them (i.e. 8 constructors) and may want to add more later on. Since the number of constructors scales exponentially with the number of parameters, I have a feeling that this approach won't scale well. Is there any elegant solution to the problem? By the way, this is why I am doing this: Depending on the values of a and b, the class chooses how to implement some parts of its interface; if a or b are not provided, it may choose generic but slow fall back implementations. If there is any other solution to that problem, I also would like to know. Thanks a lot and I hope this is how this mailing list works! Best regards, Markus MayrUnless you need to change the defaults of the values being passed in, don't pass them by template parameters. Please please please use constructors. They work at both compile time and runtime. Remember every change in template parameters equals a new type. http://dlang.org/class.html#constructors
Aug 10 2014
On Sunday, 10 August 2014 at 10:47:34 UTC, Markus Mayr wrote:Hello, I am new to D. I am sorry if this question was already answered or if it is trivial. I am having a class. That class takes several parameters that may be known at either compile time or run time. I want users of my class to be able to pass the parameters either as template parameters to the class or to the constructor of that class. At the moment, I have got the following code: class X(int a = some_dummy_value, int b = some_dummy_value) { static if (a == some_dummy_value) static immutable int a_ = a; else immutable int a_; // etc. this(int a = some_dummy_value, int b = some_dummy_value) { static if (a != some_dummy_value) this.a_ = a; static if (b != some_dummy_value) this.b_ = b; } }; This works, as far as I can tell. But there is one problem: users may forget to provide the value at compile time and run time. In that case, the members a_, b_ end up with some_dummy_values. Of course, I can notify the user at run time about this misbehaviour, but I would prefer to tell them at compile time. The only solution I am aware of is to use static if in order to provide one of four constructors depending on the compile time values of a, b, i.e. * none provided at compile time, * a provided at compile time, * b provided at compile time, * both provided at compile time. This is perfectly fine for one or two arguments, but I have gotten three of them (i.e. 8 constructors) and may want to add more later on. Since the number of constructors scales exponentially with the number of parameters, I have a feeling that this approach won't scale well. Is there any elegant solution to the problem? By the way, this is why I am doing this: Depending on the values of a and b, the class chooses how to implement some parts of its interface; if a or b are not provided, it may choose generic but slow fall back implementations. If there is any other solution to that problem, I also would like to know. Thanks a lot and I hope this is how this mailing list works! Best regards, Markus MayrA couple of words (search terms) pop up in my mind: 1) inversion of control / Dependency injection. The class has a member which does the actual work. This member is a reference to an object passed in e.g. the constructor. 2) Factory pattern A Factory determines how the object are created. Don't let the objects do that themselves. This breaks the single responsibility 'rule'. Note that a Factory works nice together with 1). 3) Inheritance. You could create multiple classes which override certain functions. This also works with 1) and 2)
Aug 10 2014