www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Object.factory() and module name

reply "eles" <eles eles.com> writes:
Creating a class instance from a string with Object.factory() 
method requires the name of the module:

http://www.informit.com/articles/article.aspx?p=1381876&seqNum=6

module main;
Human person = cast(Human)Object.factory("main.Human");

However, if one rename the module (let's say into "newmain"), he 
also has to replace all the occurences of "main.Human" into 
"newmain.Human" inside the same source file.

The situation is somewhat worse if the default module name is 
kept, that is the name of the source file. Renaming the source 
file will instantly break use of the .factory() method and, if 
the programmer is not careful to test for !is null after each 
.factory(), things get easily corrupted.

For these reasons, classes that belongs to the current module 
should (well, it's a proposal) allow a faster creation method.

Proposals:

Object.factory("Human"); // idem as Object.factory("<module 
name>.Human");

or

Object.factory(".Human"); // idem as Object.factory("<module 
name>.Human");


or

Object.factory("module.Human"); // idem as 
Object.factory("<module name>.Human");

The third proposal is, however, a bit cumbersome since requires 
the compiler to reinterpret part of a string, but it takes 
advantage of the fact that one canot name a module "module".

This way, one could rename source files without worrying for this 
issue. More, maybe it is better for the Object.factory() method 
to throw an exception instead of simply returning a null pointer 
(this will be seen even if the programmer forgot to test for null 
and is an alternative solution to the above proposals).

Opinions?
Apr 26 2013
next sibling parent "eles" <eles eles.com> writes:
On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote:

Alternatively, a function/variable could be provided inside the 
module, returning the module name as a string, so that one could 
write:

Object.factory(__MODULE__, ".Human");
Apr 26 2013
prev sibling next sibling parent Justin Whear <justin economicmodeling.com> writes:
On Fri, 26 Apr 2013 17:36:31 +0200, eles wrote:

 On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote:
 
 Alternatively, a function/variable could be provided inside the module,
 returning the module name as a string, so that one could write:
 
 Object.factory(__MODULE__, ".Human");

Instead of modifying the library, why not simply do this yourself? Object.factory(__MODULE__ ~ ".Human");
Apr 26 2013
prev sibling next sibling parent =?UTF-8?B?Ikx1w61z?= Marques" <luismarques gmail.com> writes:
On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote:
 Proposals:
 Object.factory(".Human"); // idem as Object.factory("<module 
 name>.Human");

Can't this one be done with a trivial change to the library, for strings known at compile time, by checking at compile time if the string starts with a dot? Would that be enough to alleviate the problem, or do you think more dynamic scenarios also suffer significantly from this limitation?
Apr 26 2013
prev sibling next sibling parent =?UTF-8?B?Ikx1w61z?= Marques" <luismarques gmail.com> writes:
BTW, I was working on a Object.factory scenario right now (!) and 
stumbled on the limitation that the class can only have a default 
constructor. Couldn't you call a non-default constructor by 
passing var args to Object.factory()?
Apr 26 2013
prev sibling next sibling parent "Rob T" <alanb ucora.com> writes:
On Friday, 26 April 2013 at 15:36:32 UTC, eles wrote:
 On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote:

 Alternatively, a function/variable could be provided inside the 
 module, returning the module name as a string, so that one 
 could write:

 Object.factory(__MODULE__, ".Human");

I believe __MODULE__ will be available in the next release of dmd. https://github.com/D-Programming-Language/dmd/pull/1462 --rt
Apr 26 2013
prev sibling next sibling parent "eles" <eles eles.com> writes:
On Friday, 26 April 2013 at 15:52:02 UTC, Justin Whear wrote:
 On Fri, 26 Apr 2013 17:36:31 +0200, eles wrote:

 On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote:
 
 Alternatively, a function/variable could be provided inside 
 the module,
 returning the module name as a string, so that one could write:
 
 Object.factory(__MODULE__, ".Human");

Instead of modifying the library, why not simply do this yourself? Object.factory(__MODULE__ ~ ".Human");

Sorry, this is what I intended to write, just put a comma instead of the tilda operator. However, I wasn't aware that the __MODULE__ symbol is predefined.
Apr 26 2013
prev sibling next sibling parent "eles" <eles eles.com> writes:
On Friday, 26 April 2013 at 16:13:44 UTC, Luís Marques wrote:
 BTW, I was working on a Object.factory scenario right now (!) 
 and stumbled on the limitation that the class can only have a 
 default constructor. Couldn't you call a non-default 
 constructor by passing var args to Object.factory()?

This too, seems a good idea, but let's the more experienced to decide.
Apr 26 2013
prev sibling next sibling parent "eles" <eles eles.com> writes:
On Friday, 26 April 2013 at 16:06:14 UTC, Luís Marques wrote:
 On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote:
 Proposals:
 Object.factory(".Human"); // idem as Object.factory("<module 
 name>.Human");

Can't this one be done with a trivial change to the library, for strings known at compile time, by checking at compile time if the string starts with a dot? Would that be enough to alleviate the problem, or do you think more dynamic scenarios also suffer significantly from this limitation?

The change may be trivial (and I think it is), but a decision must be reached first.
Apr 26 2013
prev sibling next sibling parent "Jacob Carlborg" <doob me.com> writes:
On Friday, 26 April 2013 at 16:13:44 UTC, Luís Marques wrote:
 BTW, I was working on a Object.factory scenario right now (!) 
 and stumbled on the limitation that the class can only have a 
 default constructor. Couldn't you call a non-default 
 constructor by passing var args to Object.factory()?

Have a look at this: https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L174 It won't call the constructor but it will create a new instance even if its construct takes arguments. You can probably call the construct using something like: instance.__ctor(args); -- /Jacob Carlborg
Apr 28 2013
prev sibling next sibling parent "Rob T" <alanb ucora.com> writes:
On Friday, 26 April 2013 at 16:13:44 UTC, Luís Marques wrote:
 BTW, I was working on a Object.factory scenario right now (!) 
 and stumbled on the limitation that the class can only have a 
 default constructor. Couldn't you call a non-default 
 constructor by passing var args to Object.factory()?

In the docs, "The class must either have no constructors or have a default constructor." I thought that meant that the class must have either no constructors at all, or if it does have constructors there must be a default constructor. That is not that same as stating that it must have only a default constructor, correct?
May 09 2013
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, May 09, 2013 20:55:43 Rob T wrote:
 On Friday, 26 April 2013 at 16:13:44 UTC, Luís Marques wrote:
 BTW, I was working on a Object.factory scenario right now (!)
 and stumbled on the limitation that the class can only have a
 default constructor. Couldn't you call a non-default
 constructor by passing var args to Object.factory()?

In the docs, "The class must either have no constructors or have a default constructor." I thought that meant that the class must have either no constructors at all, or if it does have constructors there must be a default constructor. That is not that same as stating that it must have only a default constructor, correct?

If a class doesn't have any constructors, then a default constructor is provided. - Jonathan M Davis
May 09 2013
prev sibling parent "eles" <eles eles.com> writes:
On Friday, 26 April 2013 at 15:52:02 UTC, Justin Whear wrote:
 On Fri, 26 Apr 2013 17:36:31 +0200, eles wrote:

 On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote:

Object.factory(__MODULE__ ~ ".Human");

I revive this wrt to the 2.063 release, where the __MODULE__ was added. The question that I have now is rather philosophical: The __MODULE__ is described as a "special identifier" that is "useful in debugging code" (see the 2.063 changelog, by the way, a masterpiece of changelogs, congratulations for that). So... is that OK, philosophically, to use "debug" identifiers to write something that is more like "templated" code? (the original question was about the automatically providing the module's name in the Object.factory() method). Unlike __LINE__, __MODULE__ is somewhere between the lines. Yes, now it works like that: Object.factory(__MODULE__ ~ ".Human"); But is that the recommended way to do it? Should we still aim for: Object.factory(".Human"); //if module name is not specified, the current module is assumed ?
May 30 2013