Method cascadingIn object-oriented programming, method cascading is syntax which allows multiple methods to be called on the same object. This is particularly applied in fluent interfaces. For example, in Dart, the cascade: a..b()
..c();
is equivalent to the individual calls: a.b();
a.c();
Method cascading is much less common than method chaining – it is found only in a handful of object-oriented languages, while chaining is very common. A form of cascading can be implemented using chaining, but this restricts the interface; see comparison with method chaining, below. ApplicationCascading is syntactic sugar that eliminates the need to list the object repeatedly. This is particularly used in fluent interfaces, which feature many method calls on a single object. This is particularly useful if the object is the value of a lengthy expression, as it eliminates the need to either list the expression repeatedly or use a temporary variable. For example, instead of either listing an expression repeatedly: a.b().c();
a.b().d();
or using a temporary variable: n = a.b();
n.c();
n.d();
cascading allows the expression to be written once and used repeatedly: a.b()..c()
..d();
Comparison with method chainingGiven a method call
The following chain (in C++): a.b().c();
is equivalent to the simple form: b = a.b();
b.c();
The following cascade (in Dart): a..b()
..c();
is equivalent to the simple form: a.b();
a.c();
Cascading can be implemented in terms of chaining by having the methods return the target object (receiver, LanguagesPascalWithin the component statement of the with statement, the components (fields) of the record variable specified by the with clause can be denoted by their field identifier only, i.e. without preceding them with the denotation of the entire record variable. The with clause effectively opens the scope containing the field identifiers of the specified record variable, so that the field identifiers may occur as variable identifiers. with date do
if month = 12 then
begin month := 1; year := year + 1 end
else month := month + 1
{ is equivalent to }
if date.month = 12 then
begin date.month := 1; date.year := date.year + 1 end
else date.month := date.month + 1
SmalltalkMethod chains and cascades were both introduced in Smalltalk; most subsequent object-oriented languages have implemented chains, but few have implemented cascades. In Smalltalk the semicolon operator can be used to send different messages to the same object:[1] self listPane parent
color: Color black;
height: 17;
width: 11
Compare with separate statements, terminated with a period, also using a variable for abbreviation: |parent|
parent := self listPane parent.
parent color: Color black.
parent height: 17.
parent width: 11.
One subtlety is that the value of a method call ("message") in a cascade is still the ordinary value of the message, not the receiver. This is a problem when you do want the value of the receiver, for example when building up a complex value. This can be worked around by using the special Object>>yourself
^self
For example, the "add an object to a collection" method ( all := OrderedCollection new
add: 5;
add: 7;
yourself.
Visual BasicVisual Basic uses the With ExpressionThatReturnsAnObject
.SomeFunction(42)
.Property = value
End With
With ExpressionThatReturnsAnObject
.SomeFunction(42)
.Property = value
With .SubObject
.SubProperty = otherValue
.AnotherMethod(42)
End With
End With
DartAmong newer languages, Dart implements cascades, using a double-dot a..string = 'Hello world!'
..done = true;
is equivalent to: a.string = 'Hello world!';
a.done = true;
LispsThe builtin (doto (java.util.ArrayList.)
(.add 1)
(.add 3)
(println)) ;not limited to methods
;;; expands to code equivalent to
(let [l (java.util.ArrayList.)]
(.add l 1)
(.add l 3)
(println l)
l) ; the form evaluates to the first input
Similar macros are available or can be easily defined in various other lisps like Common Lisp. References
External links
Information related to Method cascading |