Skip to content

Instantly share code, notes, and snippets.

@JesseKPhillips
Last active January 4, 2016 12:29
Show Gist options
  • Save JesseKPhillips/8621413 to your computer and use it in GitHub Desktop.
Save JesseKPhillips/8621413 to your computer and use it in GitHub Desktop.
This shows that hiding implementation behind a function and provide a very simple client interface. As per a conversation on reddit: http://www.reddit.com/r/programming/comments/1w2xpl/selfreferential_functions_and_the_design_of/cey8y4v
import std.stdio;
@safe:
void main() {
Foo foo;
foo.Option.Val2 = "bye";
myFun(foo);
foo.DoSomeDebugging();
}
void myFun(ref Foo foo) {
auto prev = foo.Option.save;
scope(exit) foo.Option = prev;
// Use proper typing while I'm at it
foo.Option.Verbosity = Foo.Verbosity.full;
foo.Option.Val2 = "hello";
foo.DoSomeDebugging();
}
struct Foo {
private:
Properties p;
public:
enum Verbosity { error, warn, hiphop, full }
void DoSomeDebugging() @trusted {
writeln();
writeln("Verbose: ", p.Verbosity);
writeln("Val2: ", p.Val2);
}
@property auto Option() {
return Wrapper(&p);
}
@property void Option(Properties prop) {
p = prop;
}
// Declare a type which holds reference to Foo's properties. Since Foo is
// a structure, this wrapper shouldn't exist once Foo goes out of scope,
// since use will result in segfault.
struct Wrapper {
Properties* prop;
// The wrapper can convert to a saved property any time
alias save this;
// Each property will set the values utilized by Foo
@property void Verbosity(Foo.Verbosity fv) {
prop.Verbosity = fv;
}
@property void Val2(string val) {
prop.Val2 = val;
}
@property Properties save() {
return *prop;
}
}
}
// Use a simple struct
// could change to functions if desired.
struct Properties {
string _val2;
Foo.Verbosity Verbosity;
@property string Val2() {
return _val2;
}
@property void Val2(string v) {
_val2 = v;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment