The idea is that each method call will augment the item it was called on. Internally, this is pretty straightforward:
class AnyNode(...){ def cls(v: String) = this.copy(classes = v :: this.classes)
}
Where each call does a copy-and-update, returning the newly created object.
My problem is that some methods only exist on sub-classes. For example, I want to be able to do
table.head(...).body(...)
while disallowing
div.head(...).body(...)
Hence "head()" is defined as a method of the Table class, and not of the AnyNode class. However, all the generic operations are defined on the AnyNode class, and thus return objects of type AnyNode. As a result, I can do this:
table.head(...).cls("bordered")
but I cannot do this
table.cls("bordered").head(...)
because cls returns an AnyNode. Is there any way to get cls (which Table inherited from AnyNode), when called on a instance of Table, to return another instance of Table? Or is it impossible, and should I be trying a different approach to this?
> The idea is that each method call will augment the item it was called > on. Internally, this is pretty straightforward:
> class AnyNode(...){ > def cls(v: String) = this.copy(classes = v :: this.classes) > }
> Where each call does a copy-and-update, returning the newly created > object.
> My problem is that some methods only exist on sub-classes. For > example, I want to be able to do
> table.head(...).body(...)
> while disallowing
> div.head(...).body(...)
> Hence "head()" is defined as a method of the Table class, and not of > the AnyNode class. However, all the generic operations are defined on > the AnyNode class, and thus return objects of type AnyNode. As a > result, I can do this:
> table.head(...).cls("bordered")
> but I cannot do this
> table.cls("bordered").head(...)
> because cls returns an AnyNode. Is there any way to get cls (which > Table inherited from AnyNode), when called on a instance of Table, to > return another instance of Table? Or is it impossible, and should I be > trying a different approach to this?
> class Node { > def cls(c: String): this. type = { whatever; this } > }
this.type means “exactly this object”, which does not fit the OP’s requirements (return updated copy). Unfortunately, the issue is not a simple one, search this group for MyType. In essence you would need to go the same route as the collections library (using the CanBuildFrom pattern).
>> The idea is that each method call will augment the item it was called on. Internally, this is pretty straightforward:
>> class AnyNode(...){ >> def cls(v: String) = this.copy(classes = v :: this.classes) >> }
>> Where each call does a copy-and-update, returning the newly created object.
>> My problem is that some methods only exist on sub-classes. For example, I want to be able to do
>> table.head(...).body(...)
>> while disallowing
>> div.head(...).body(...)
>> Hence "head()" is defined as a method of the Table class, and not of the AnyNode class. However, all the generic operations are defined on the AnyNode class, and thus return objects of type AnyNode. As a result, I can do this:
>> table.head(...).cls("bordered")
>> but I cannot do this
>> table.cls("bordered").head(...)
>> because cls returns an AnyNode. Is there any way to get cls (which Table inherited from AnyNode), when called on a instance of Table, to return another instance of Table? Or is it impossible, and should I be trying a different approach to this?
>> Thanks! >> -Haoyi
Roland Kuhn Typesafe – The software stack for applications that scale. twitter: @rolandkuhn
> The idea is that each method call will augment the item it was called on.
> Internally, this is pretty straightforward:
> class AnyNode(...){
> def cls(v: String) = this.copy(classes = v :: this.classes)
> }
> Where each call does a copy-and-update, returning the newly created object.
> My problem is that some methods only exist on sub-classes. For example, I
> want to be able to do
> table.head(...).body(...)
> while disallowing
> div.head(...).body(...)
> Hence "head()" is defined as a method of the Table class, and not of the
> AnyNode class. However, all the generic operations are defined on the
> AnyNode class, and thus return objects of type AnyNode. As a result, I can
> do this:
> table.head(...).cls("bordered")
> but I cannot do this
> table.cls("bordered").head(...)
> because cls returns an AnyNode. Is there any way to get cls (which Table
> inherited from AnyNode), when called on a instance of Table, to return
> another instance of Table? Or is it impossible, and should I be trying a
> different approach to this?