www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Theoretical Best Practices

reply "DarthCthulhu" <spam spam.com> writes:
This is more a theoretical exercise than specific code nitty 
gritty, but...

Let's say I have some code like this:

class World {

	// Bunch of members and other functions

	void happyDay () {

		if (bCthulhuRises) {

			debug(logging) {

				logger.writeLog(this); // uses the class toString to give a 
dump of interesting parts of the object
			}

			throw new Exception("We're doomed! Run you fools!");

		}

	}

}

I only want to access the logger object when the program is 
compiled with the -debug option, so I don't want to pass it along 
to the object constructor or set a member as a reference to it 
(which is both tedious and pointless if not in -debug mode). The 
simple solution is to make the Logger class a singleton (can D do 
singletons? I presume it's possible, but I haven't really looked 
into it), but is there a means in D that is considered a better 
way to do this?
Aug 14 2015
next sibling parent "QAston" <qaston gmail.com> writes:
On Friday, 14 August 2015 at 09:21:56 UTC, DarthCthulhu wrote:
 I only want to access the logger object when the program is 
 compiled with the -debug option, so I don't want to pass it 
 along to the object constructor or set a member as a reference 
 to it (which is both tedious and pointless if not in -debug 
 mode). The simple solution is to make the Logger class a 
 singleton (can D do singletons? I presume it's possible, but I 
 haven't really looked into it), but is there a means in D that 
 is considered a better way to do this?
D can do singletons, the regular java/c# way, or you can just have an object on a module level. You can also debug{} the field.
Aug 14 2015
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 8/14/15 5:21 AM, DarthCthulhu wrote:
 This is more a theoretical exercise than specific code nitty gritty, but...

 Let's say I have some code like this:

 class World {

      // Bunch of members and other functions

      void happyDay () {

          if (bCthulhuRises) {

              debug(logging) {

                  logger.writeLog(this); // uses the class toString to
 give a dump of interesting parts of the object
              }

              throw new Exception("We're doomed! Run you fools!");

          }

      }

 }

 I only want to access the logger object when the program is compiled
 with the -debug option, so I don't want to pass it along to the object
 constructor or set a member as a reference to it (which is both tedious
 and pointless if not in -debug mode). The simple solution is to make the
 Logger class a singleton (can D do singletons? I presume it's possible,
 but I haven't really looked into it), but is there a means in D that is
 considered a better way to do this?
I would do it this way: // at module level debug(logging) { Logger logger; static this() { logger = new Logger;} } If you want to have the logger be global, add 'shared' to both the logger and the static this. This initializes the data before main() is run, so there is no need for singletons. The added bonus here is that you can't accidentally log stuff when debug(logging) isn't enabled, as the variable will not exist. -Steve
Aug 14 2015
parent reply "DarthCthulhu" <spam spam.com> writes:
On Friday, 14 August 2015 at 12:40:08 UTC, Steven Schveighoffer 
wrote:
 I would do it this way:

 // at module level
 debug(logging) {
     Logger logger;
     static this() { logger = new Logger;}
 }

 If you want to have the logger be global, add 'shared' to both 
 the logger and the static this.

 This initializes the data before main() is run, so there is no 
 need for singletons.

 The added bonus here is that you can't accidentally log stuff 
 when debug(logging) isn't enabled, as the variable will not 
 exist.

 -Steve
Ahh, that is a much cleaner way to do it rather than using a singleton. By 'module level', I assume you mean in the module that defines the Logger class? An 'import debug.logger' or somesuch would then give all relevant modules access, correct? Is the compiler smart enough to compile out all the symbols associated with the logger if it is never instantiated?
Aug 14 2015
next sibling parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Friday, 14 August 2015 at 22:25:15 UTC, DarthCthulhu wrote:
 Ahh, that is a much cleaner way to do it rather than using a 
 singleton.

 By 'module level', I assume you mean in the module that defines 
 the Logger class? An 'import debug.logger' or somesuch would 
 then give all relevant modules access, correct?

 Is the compiler smart enough to compile out all the symbols 
 associated with the logger if it is never instantiated?
If you want to make 100% sure that the Logger code does not end up in the release version, you can just put the Logger class definition in that debug block as well. Also, am I the only one who is imagining that you are really the dog in your avatar. I am just imagining that there is a dog somewhere trying to learn D.
Aug 14 2015
parent "DarthCthulhu" <spam spam.com> writes:
On Friday, 14 August 2015 at 23:17:44 UTC, Tofu Ninja wrote:
 On Friday, 14 August 2015 at 22:25:15 UTC, DarthCthulhu wrote:
 Ahh, that is a much cleaner way to do it rather than using a 
 singleton.

 By 'module level', I assume you mean in the module that 
 defines the Logger class? An 'import debug.logger' or somesuch 
 would then give all relevant modules access, correct?

 Is the compiler smart enough to compile out all the symbols 
 associated with the logger if it is never instantiated?
If you want to make 100% sure that the Logger code does not end up in the release version, you can just put the Logger class definition in that debug block as well.
Well, it doesn't really matter much as a logger class wouldn't have very much in it anyway. But I am imagining some kind of uber-huge class might be used for some reason in other ways and it would be interesting to know if it would be cut out completely by the compiler or not.
 Also, am I the only one who is imagining that you are really 
 the dog in your avatar. I am just imagining that there is a dog 
 somewhere trying to learn D.
WHO TOLD YOU!? Er, I mean, gee-whilikers, why would you think that? I am a perfectly normal human. Yessiree, human hands an evryting. no annoyingly fat paws that make it hard to type. Now if you'll excuse me, I have to go walkies.
Aug 14 2015
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 8/14/15 6:25 PM, DarthCthulhu wrote:
 On Friday, 14 August 2015 at 12:40:08 UTC, Steven Schveighoffer wrote:
 I would do it this way:

 // at module level
 debug(logging) {
     Logger logger;
     static this() { logger = new Logger;}
 }
By 'module level', I assume you mean in the module that defines the Logger class? An 'import debug.logger' or somesuch would then give all relevant modules access, correct?
I mean, in global scope (which is defined as being part of the module). Not inside a class/struct/function.
 Is the compiler smart enough to compile out all the symbols associated
 with the logger if it is never instantiated?
If it's never instantiated, and it's a template, then it will not be compiled in. If it's not a template, it could potentially make it into the binary. -Steve
Aug 17 2015