Dart and Smalltalk have a cascade method .
It seems that a similar style can be achieved with do with .
For example, here is a simple program that uses GTK::Simple :
use v6; use GTK::Simple; my $app = GTK::Simple::App.new(title => "abc"); $app.set-content( GTK::Simple::VBox.new( my $button_a = GTK::Simple::Button.new(label => 'bcd'), my $button_b = GTK::Simple::Button.new(label => 'cde') ) ); $app.border-width = 20; $button_a.clicked.tap({ .sensitive = False; $button_b.sensitive = True }); $button_b.sensitive = False; $button_b.clicked.tap({ $app.exit }); $app.run;
Here's an equivalent program that uses do with in several places to achieve an effect similar to method cascades:
use v6; use GTK::Simple; my $app; my $button_a; my $button_b; do with GTK::Simple::App.new(title => 'abc') { $app = $_; .set-content( GTK::Simple::VBox.new( $button_a = do with GTK::Simple::Button.new(label => 'bcd') { .clicked.tap({ .sensitive = False; $button_b.sensitive = True }); $_ }, $button_b = do with GTK::Simple::Button.new(label => 'cde') { .sensitive = False; .clicked.tap({ $app.exit }); $_ } ) ); .border-width = 20; .run; };
My question is, is there a more idiomatic way to express the cascading style of a method in Perl 6?
The downside of do with is that you must explicitly return $_ . With traditional cascades of methods, the original recipient object is implicitly returned.
For example, $button_a is set here:
$button_a = do with GTK::Simple::Button.new(label => 'bcd') { .clicked.tap({ .sensitive = False; $button_b.sensitive = True }); $_ }
It would be nice if $_ did not need to be explicitly explained. For example, something like:
$button_a = do cascade GTK::Simple::Button.new(label => 'bcd') { .clicked.tap({ .sensitive = False; $button_b.sensitive = True }); }
Another drawback of do with is that the syntax is heavier than the syntax of the cascading Dart and Smalltalk methods. Something closer to the Dart type might look like this:
$button_a = GTK::Simple::Button.new(label => 'bcd') ..clicked.tap({ .sensitive = False; $button_b.sensitive = True });