www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [Bikeshed] getter/readonly mixin util with private/protected backing

reply "Nick Sabalausky" <a a.a> writes:
In my SemiTwist D Tools project ( 
http://www.dsource.org/projects/semitwist ), I have a util mixin to DRY-ly 
create a publically-readonly property with backing storage (actually, I've 
had it for awhile, but I've been toying with it again recently).

1. It can optionally give the backing storage any access level you want, but 
what I'm wondering is, what do you think would be a better default: private 
or protected?

2. As a secondary question, do you think 'getter', 'readonly' or something 
else would be the best name for it?

3. There's an alternate version that creates a getter that, instead of 
returning the backing storage, works like this: On the first call, a 
user-supplied function is called that generates the value. This value is 
automatically cached and returned. Subsequent calls return the cached value 
until the private (or protected) 'cached' flag is cleared. What would be a 
good name for this util? 'getterLazy', 'getterCached', 'readonlyLazy', 
'readonlyCached', etc..., or just simply overload the regular 
'getter'/'readonly'/etc...?

4. Do you think this util would be a useless waste, or potentially handy?

My main interest is Q #1, but I'm curious about opinions on the others too. 
Nov 11 2009
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
Nick Sabalausky wrote:

 In my SemiTwist D Tools project (
 http://www.dsource.org/projects/semitwist ), I have a util mixin to DRY-ly
 create a publically-readonly property with backing storage (actually, I've
 had it for awhile, but I've been toying with it again recently).
 
 1. It can optionally give the backing storage any access level you want,
 but what I'm wondering is, what do you think would be a better default:
 private or protected?

Private for sure.
 2. As a secondary question, do you think 'getter', 'readonly' or something
 else would be the best name for it?

getter is the clearest imho.
 3. There's an alternate version that creates a getter that, instead of
 returning the backing storage, works like this: On the first call, a
 user-supplied function is called that generates the value. This value is
 automatically cached and returned. Subsequent calls return the cached
 value until the private (or protected) 'cached' flag is cleared. What
 would be a good name for this util? 'getterLazy', 'getterCached',
 'readonlyLazy', 'readonlyCached', etc..., or just simply overload the
 regular 'getter'/'readonly'/etc...?

What about passing both this and access level as a parameter to the template? Something like this perhaps: mixin ( getter!("myFunc", "myInitializer", PROTECTED | LAZY) );
 4. Do you think this util would be a useless waste, or potentially handy?
 
 My main interest is Q #1, but I'm curious about opinions on the others
 too.
 

Might be handy depending on the kind of things you are going to write.
Nov 12 2009
parent reply Justin Johansson <no spam.com> writes:
Lutger Wrote:

 Nick Sabalausky wrote:
 
 In my SemiTwist D Tools project (
 http://www.dsource.org/projects/semitwist ), I have a util mixin to DRY-ly
 create a publically-readonly property with backing storage (actually, I've
 had it for awhile, but I've been toying with it again recently).
 
 1. It can optionally give the backing storage any access level you want,
 but what I'm wondering is, what do you think would be a better default:
 private or protected?

Private for sure.
 2. As a secondary question, do you think 'getter', 'readonly' or something
 else would be the best name for it?

getter is the clearest imho.
 3. There's an alternate version that creates a getter that, instead of
 returning the backing storage, works like this: On the first call, a
 user-supplied function is called that generates the value. This value is
 automatically cached and returned. Subsequent calls return the cached
 value until the private (or protected) 'cached' flag is cleared. What
 would be a good name for this util? 'getterLazy', 'getterCached',
 'readonlyLazy', 'readonlyCached', etc..., or just simply overload the
 regular 'getter'/'readonly'/etc...?

What about passing both this and access level as a parameter to the template? Something like this perhaps: mixin ( getter!("myFunc", "myInitializer", PROTECTED | LAZY) );
 4. Do you think this util would be a useless waste, or potentially handy?
 
 My main interest is Q #1, but I'm curious about opinions on the others
 too.
 

Might be handy depending on the kind of things you are going to write.

Nick, On the surface Lutger's answers seem pretty reasonable but that's without knowing more about the finer details of your project. However, having looked at the project link I think you are more likely to get better informed, and more, replies if you told us a bit more about the problem(s) the SemiTwist Tools project is trying to solve. I'm interested in being helpful (and hope this reply is) but can you expand the project detail a little to solicit a wider audience? Regards Justin
Nov 12 2009
parent "Nick Sabalausky" <a a.a> writes:
"Justin Johansson" <no spam.com> wrote in message 
news:hdgl0n$dc7$1 digitalmars.com...
 Nick,

 On the surface Lutger's answers seem pretty reasonable but that's without 
 knowing
 more about the finer details of your project.

 However, having looked at the project link I think you are more likely to 
 get better
 informed, and more, replies if you told us a bit more about the problem(s) 
 the SemiTwist
 Tools project is trying to solve.  I'm interested in being helpful (and 
 hope this reply is)
 but can you expand the project detail a little to solicit a wider 
 audience?

 Regards Justin

Good question. The "SemiTwist" probably makes it confusing, but all it is is a collection of potentially useful utility libraries and tools (cross-platform, although only tested on Win/Lin). Basically it's kind of like my own scrapple, except it's all in one big cohesive package. It started out as my own personal utility library, but then grew and grew and grew. Different parts of it are in different stages of development, ie, a few things are barely just skeleton apps, but other things are far enough that they've become part of my everyday workflow. Still needs a little cleanup and some docs before it'll deserve a formal release-with-announcement, but it is there. Examples of some things in it: - util.mixins (lib, fully-usable, still keep tweaking now-and-then): Work-saving mixins for DRY fans. The getter stuff from my OP (because making read-only member vars in D is often needed but absurdly verbose), trace file/line, trace a value while *also* displaying just WTF the value was computed from (ex: If foo == 6, and you want to display foo+1, then you see "foo+1: 7" in the output instead of just "7" without having to duplicate "foo+1" and remember to keep it in sync.) I recently outlined many of these over on D.announce."Metaprogramming in D: Some Real-World Examples" - util.deferAssert (lib, fully-usable, but I have ideas for improvement): Somewhere between D's assert() and JUnit. Proves that you can get *good* unittest diagnostics without a doing garbage like "(a.notEqual(b)).logicalOr(c.greaterThan(d))" and then loading up a big fancy test-runner tool...unless you use Java, of course, then you're SOL. Mentioned more over on D.announce."Metaprogramming in D: Some Real-World Examples" - ver (lib, works, but needs another feature-or-two): Floats have one decimal point, but version numbers can have an arbitrary number, and comparing version numbers using any built-in prmitive is highly non-general and ugly. This makes a Ver struct (compatible with strings and int[]) and abstracts that all away. - cmd (lib, alpha-level): Despite stuff like rdmd, D's std libs don't lend themselves well as a replacement for doing quick shell scripting stuff, unlike bash or perl or (I presume) python. This is a lib that provides a shell-like interface through a ready-to-use "cmd.xxxxx" object, and optionally adds in the proverbial kicken-sink. Bad for big projects, but aims to make D a good choice for short scripts (hunting through API docs for the right import, and many things that are good for big projects, are real buzz-kills for quick scripting). - cmdlineparser (lib, fully-usable, needs API cleanup and some features): Yet another command-line parser. I like it. superdan hates its design. - stbuild (tool, works, I use it daily, but very feature-sparse and rigid atm): Command-line front-end for rebuild (will support others like xfbuild later) for managing command-line switches for multiple build targets (ie, "toolA.exe", "toolB.exe" etc.) and configurations (ie, "debug", "release") and cleaning. This lets me avoid having to ship apps with platform-specific batch and shell files (except for bootstrapping stbuild itself) just to send rebuild the appropriate switches for different apps and configurations. Plan to expand it later. - seterrorlevel (tool, fully working): Does what it says, sometimes useful for batch. - myecho (tool, fully working but lacks "-n"): It's echo, seems useless, but on windows "echo" is part of the shell, not an actual executable, so it can't be launched as a process, which is a pain for making cross-platform examples/unittests of process-launching functions. - showargs (tool, fully working): Displays the args it's given, numbered, with one per line. Useful for testing process-launching code.
Nov 12 2009