www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - chaining

reply Brian <digitalmars brianguertin.com> writes:
I want to use a chaining system for easy setting of object attributes, 
which would work great for a single object, unfortunately derived classes 
cannot inherit the chained functions implicitly, whats the best way 
around this?

class Base {
	int x;
	Base foo(int x_) {
		this.x = x_;
		return this;
	}
}

class Derived : Base {
	Derived bar(int y_) {
		return this;
	}
}

// usage:
auto m = (new Derived).foo(10).bar(x); // bar can be accessed through foo
Feb 25 2009
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Brian,

 I want to use a chaining system for easy setting of object attributes,
 which would work great for a single object, unfortunately derived
 classes cannot inherit the chained functions implicitly, whats the
 best way around this?
 
 class Base {
 int x;
 Base foo(int x_) {
 this.x = x_;
 return this;
 }
 }
 class Derived : Base {
 Derived bar(int y_) {
 return this;
 }
 }
 // usage:
 auto m = (new Derived).foo(10).bar(x); // bar can be accessed through
 foo
mixins: template BaseT(){ typeof(this) foo()(int x_) { this.x = x_; return this; } } class Base { int x; mixin BaseT!(); } template DerivedT() { typeof(this) bar(int y_) { return this; } mixin BaseT!(); } class Derived : Base { mixin DerivedT!(); } void main() { int x; // usage: auto m = (new Derived).foo(10).bar(x); // bar can be accessed through foo }
Feb 25 2009
parent reply Brian <digitalmars brianguertin.com> writes:
On Wed, 25 Feb 2009 22:08:43 +0000, BCS wrote:
 template BaseT(){
     typeof(this) foo()(int x_) {
         this.x = x_;
         return this;
     }
 }
 class Base {
     int x;
     mixin BaseT!();
 }
 
 template DerivedT()
 {
     typeof(this) bar(int y_) {
         return this;
     }
     mixin BaseT!();
 }
 class Derived : Base {
     mixin DerivedT!();
 }
hmm.. is that really the best way? if the function has 10 lines of code and is mixed into to 15 classes thatll give me 15 times the code for that one function i think. also gets a bit tricky when i want to override some of the functions. (by using another class in between base and derived?). i think i need a new plan..
Feb 26 2009
parent BCS <ao pathlink.com> writes:
Reply to Brian,

 On Wed, 25 Feb 2009 22:08:43 +0000, BCS wrote:
 
 template BaseT(){
 typeof(this) foo()(int x_) {
 this.x = x_;
 return this;
 }
 }
 class Base {
 int x;
 mixin BaseT!();
 }
 template DerivedT()
 {
 typeof(this) bar(int y_) {
 return this;
 }
 mixin BaseT!();
 }
 class Derived : Base {
 mixin DerivedT!();
 }
hmm.. is that really the best way? if the function has 10 lines of code and is mixed into to 15 classes thatll give me 15 times the code for that one function i think. also gets a bit tricky when i want to override some of the functions. (by using another class in between base and derived?). i think i need a new plan..
you could stuff all the functonality into non-mixedin functions and only mix in shells template DerivedT() { typeof(this) bar(int y_) { do_bar(y_); return this; } }
Feb 26 2009
prev sibling parent reply grauzone <none example.net> writes:
Brian wrote:
 I want to use a chaining system for easy setting of object attributes, 
 which would work great for a single object, unfortunately derived classes 
 cannot inherit the chained functions implicitly, whats the best way 
 around this?
 
 class Base {
 	int x;
 	Base foo(int x_) {
 		this.x = x_;
 		return this;
 	}
 }
 
 class Derived : Base {
 	Derived bar(int y_) {
 		return this;
 	}
 }
 
 // usage:
 auto m = (new Derived).foo(10).bar(x); // bar can be accessed through foo
Couldn't you just write the above example as: auto m = new Derived; m.foo(10); m.bar(x); This is actually much more readable: the reader doesn't need to know that the functions foo and bar return m; instead, the code uses m directly. Obviously, this is also simpler to implement than chaining. I don't get why some people like chaining. Unlike in languages like C++, you can always use "auto" to keep the typing to a minimum. What more arguments are there for chaining?
Feb 26 2009
parent Brian <digitalmars brianguertin.com> writes:
On Thu, 26 Feb 2009 09:45:28 +0100, grauzone wrote:

 Brian wrote:
 I want to use a chaining system for easy setting of object attributes,
 which would work great for a single object, unfortunately derived
 classes cannot inherit the chained functions implicitly, whats the best
 way around this?
 
 class Base {
 	int x;
 	Base foo(int x_) {
 		this.x = x_;
 		return this;
 	}
 }
 
 class Derived : Base {
 	Derived bar(int y_) {
 		return this;
 	}
 }
 
 // usage:
 auto m = (new Derived).foo(10).bar(x); // bar can be accessed through
 foo
Couldn't you just write the above example as: auto m = new Derived; m.foo(10); m.bar(x); This is actually much more readable: the reader doesn't need to know that the functions foo and bar return m; instead, the code uses m directly. Obviously, this is also simpler to implement than chaining. I don't get why some people like chaining. Unlike in languages like C++, you can always use "auto" to keep the typing to a minimum. What more arguments are there for chaining?
your probably right.. it also looks simpler written out. i do sort of use chaining to create dictionaries of variant/box objects, though it could probably just be a function with variable arguments. i think it looks neat. sig.emit((new Message) ("number", 24) ("str", "hello") ("obj", someobject) ("and-so-on", [1,2,3]) );
Feb 27 2009