www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - First Steps: Dynamic class instantiation

reply Thomas <thc forestfactory.de> writes:
Hi

I'm just making my first steps to understand D, and sometimes I'm a little bit
offroad as I do not know C/C++, just PHP, Javascript etc.

I would like to write a small shell application with a small bundle of
functionalities. As a first step, the user must choose which function to use (I
already got that part). Than she must enter some information for the function
to work on.

I thought of doing this by creating classes for each functionality implementing
the same interface and creating an array in main() that somehow refers to these
classes. There the trouble starts.

I don't know how to create such an array, and of which type it has to be. To be
more specific, I provide you with a PHP example of what I want to do:

$selected = 1;
$classes = array('class1','class2');
$className = $classes[$selected];
$object = new $className;

Thanks for any help.

Thomas
Jan 27 2007
next sibling parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Thomas wrote:
 Hi
 
 I'm just making my first steps to understand D, and sometimes I'm a little bit
offroad as I do not know C/C++, just PHP, Javascript etc.
 
 I would like to write a small shell application with a small bundle of
functionalities. As a first step, the user must choose which function to use (I
already got that part). Than she must enter some information for the function
to work on.
 
 I thought of doing this by creating classes for each functionality
implementing the same interface and creating an array in main() that somehow
refers to these classes. There the trouble starts.
 
 I don't know how to create such an array, and of which type it has to be. To
be more specific, I provide you with a PHP example of what I want to do:
 
 $selected = 1;
 $classes = array('class1','class2');
 $className = $classes[$selected];
 $object = new $className;
 
 Thanks for any help.
 

This can't really be done in D, which is statically typed. Languages like PHP are dynamically typed. You'll have to do some re-thinking of your design, I think. First, you'll want all of your classes to either derive from the same class or implement the same interface. Let's call this base class (or interface) Base. You could try something like this: int selected = 1; Base object; switch (selected) { case 1: object = new Class1; break; case 2: object = new Class2; break; // and so on } You might also consider using an enum instead of an int for selected. -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org
Jan 27 2007
next sibling parent Thomas <thc forestfactory.de> writes:
Kirk McDonald Wrote:

 Thomas wrote:
 
 I thought of doing this by creating classes for each functionality
implementing the same interface and creating an array in main() that somehow
refers to these classes. There the trouble starts.
 

like PHP are dynamically typed. You'll have to do some re-thinking of your design, I think.

Thanks a lot. I will exercise a little more with that information.
Jan 27 2007
prev sibling parent Benji Smith <dlanguage benjismith.net> writes:
Kirk McDonald wrote:
 This can't really be done in D, which is statically typed. Languages 
 like PHP are dynamically typed. You'll have to do some re-thinking of 
 your design, I think.

Well, Java is statically typed, and it can do what the OP requested. It's not really a question of dynamic/static typing. It's more a question of whether runtime reflection is supported. And right now, D's runtime reflection capabilities aren't as complete as Java's. Personally, I'm not crazy about reflection-heavy code, since I think it provides a sneaky mechanism for subverting the compile-time type-checking system. Debugging Java code that makes heavy use of reflection is not a pleasant experience (since all of your exceptions get swallowed up in the reflection API, as InvocationTargetExceptions). --benji
Jan 28 2007
prev sibling next sibling parent "Lionello Lunesu" <lionello lunesu.remove.com> writes:
Hi Thomas,

'The other' Thomas (Khuene) has created a lib, Flectioned, that can do just 
that. IRC, it only works for linux.

http://flectioned.kuehne.cn

L. 
Jan 28 2007
prev sibling next sibling parent S. <S s.com> writes:
On 2007-01-27 19:30:04 -0800, Thomas <thc forestfactory.de> said:

 Hi
 
 I'm just making my first steps to understand D, and sometimes I'm a 
 little bit offroad as I do not know C/C++, just PHP, Javascript etc.
 
 I would like to write a small shell application with a small bundle of 
 functionalities. As a first step, the user must choose which function 
 to use (I already got that part). Than she must enter some information 
 for the function to work on.
 
 I thought of doing this by creating classes for each functionality 
 implementing the same interface and creating an array in main() that 
 somehow refers to these classes. There the trouble starts.
 
 I don't know how to create such an array, and of which type it has to 
 be. To be more specific, I provide you with a PHP example of what I 
 want to do:
 
 $selected = 1;
 $classes = array('class1','class2');
 $className = $classes[$selected];
 $object = new $className;
 
 Thanks for any help.
 
 Thomas

I'm not sure what you'd be doing where this would be an optimal solution, but you can do something like this: ushort selected = 1; Object[] classes = [new Class1, new Class2]; Object foo = classes[selected].dup; I believe....
Jan 28 2007
prev sibling next sibling parent reply Kevin Bealer <kevinbealer gmail.com> writes:
Thomas wrote:
 Hi
 
 I'm just making my first steps to understand D, and sometimes I'm a little bit
offroad as I do not know C/C++, just PHP, Javascript etc.
 
 I would like to write a small shell application with a small bundle of
functionalities. As a first step, the user must choose which function to use (I
already got that part). Than she must enter some information for the function
to work on.
 
 I thought of doing this by creating classes for each functionality
implementing the same interface and creating an array in main() that somehow
refers to these classes. There the trouble starts.
 
 I don't know how to create such an array, and of which type it has to be. To
be more specific, I provide you with a PHP example of what I want to do:
 
 $selected = 1;
 $classes = array('class1','class2');
 $className = $classes[$selected];
 $object = new $className;
 
 Thanks for any help.
 
 Thomas

(This probably goes in D.learn by the way.) If you have a class that follows a common interface (I'll call it Command) you could do this: class Command { static Command[char[]] actions; this(char[] name) { actions[name] = this; } static void run(char[] name, char[] arguments) { assert(name in actions); actions[name].work(arguments); } abstract void work(char[] arguments); }; Then you can create instance of Command: class Rename : Command { this() { super("rename"); } void work(char[] arguments) { // do a rename or something } }; If you create one object of each subclass: Rename r = new Rename; The calling code could do this: Command.run("rename", "a b"); Which would run the Rename.work() command. Kevin
Jan 28 2007
parent Kyle Furlong <kylefurlong gmail.com> writes:
Kevin Bealer wrote:
 Thomas wrote:
 Hi

 I'm just making my first steps to understand D, and sometimes I'm a 
 little bit offroad as I do not know C/C++, just PHP, Javascript etc.

 I would like to write a small shell application with a small bundle of 
 functionalities. As a first step, the user must choose which function 
 to use (I already got that part). Than she must enter some information 
 for the function to work on.

 I thought of doing this by creating classes for each functionality 
 implementing the same interface and creating an array in main() that 
 somehow refers to these classes. There the trouble starts.

 I don't know how to create such an array, and of which type it has to 
 be. To be more specific, I provide you with a PHP example of what I 
 want to do:

 $selected = 1;
 $classes = array('class1','class2');
 $className = $classes[$selected];
 $object = new $className;

 Thanks for any help.

 Thomas

(This probably goes in D.learn by the way.) If you have a class that follows a common interface (I'll call it Command) you could do this: class Command { static Command[char[]] actions; this(char[] name) { actions[name] = this; } static void run(char[] name, char[] arguments) { assert(name in actions); actions[name].work(arguments); } abstract void work(char[] arguments); }; Then you can create instance of Command: class Rename : Command { this() { super("rename"); } void work(char[] arguments) { // do a rename or something } }; If you create one object of each subclass: Rename r = new Rename; The calling code could do this: Command.run("rename", "a b"); Which would run the Rename.work() command. Kevin

Wow, that is an effective solution, never seen that pattern before.
Jan 28 2007
prev sibling next sibling parent =?ISO-8859-1?Q?Julio_C=E9sar_Carrascal_Urquijo?= writes:
Thomas wrote:
 Hi
 
 I'm just making my first steps to understand D, and sometimes I'm a little bit
offroad as I do not know C/C++, just PHP, Javascript etc.
 
 I would like to write a small shell application with a small bundle of
functionalities. As a first step, the user must choose which function to use (I
already got that part). Than she must enter some information for the function
to work on.
 
 I thought of doing this by creating classes for each functionality
implementing the same interface and creating an array in main() that somehow
refers to these classes. There the trouble starts.
 
 I don't know how to create such an array, and of which type it has to be. To
be more specific, I provide you with a PHP example of what I want to do:
 
 $selected = 1;
 $classes = array('class1','class2');
 $className = $classes[$selected];
 $object = new $className;
 
 Thanks for any help.
 
 Thomas

Jan 28 2007
prev sibling parent reply =?ISO-8859-1?Q?Julio_C=E9sar_Carrascal_Urquijo?= writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Thomas wrote:
 $selected = 1;
 $classes = array('class1','class2');
 $className = $classes[$selected];
 $object = new $className;
 
 Thanks for any help.
 
 Thomas

This version is very similar an more efficient though the array initialization is more verbose.
Jan 28 2007
parent Thomas Forster (to be specific) <thc forestfactory.de> writes:
Thanks to all of you. After tying all your suggestions, I think that Julios
fits best my needs to make it as easy as possible to add a new command. I can
add a class and "register" it to the CommandFactory, and that's it.

Regards

Thomas
Jan 28 2007