2016-06-01 47 views
6

Dart和Smalltalk有method cascades方法級聯語法

似乎可以通過do with實現類似的風格。

例如,這裏有一個簡單的程序,其採用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; 

下面是使用在一些地方do with才達到類似方法層疊效果的同等功能的程序:

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; 
}; 

我的問題是否,在Perl 6中有沒有一種更習慣於表達方法級聯風格的方式?

缺點do with是你必須明確地返回$_。使用傳統的方法級聯,原始接收器對象被隱式返回。

例如,這裏的$button_a是如何設置的:

$button_a = do with GTK::Simple::Button.new(label => 'bcd') 
{ 
    .clicked.tap({ .sensitive = False; $button_b.sensitive = True }); 
    $_ 
} 

這將是很好,如果$_沒有被explicly返回。例如,像:

$button_a = do cascade GTK::Simple::Button.new(label => 'bcd') 
{ 
    .clicked.tap({ .sensitive = False; $button_b.sensitive = True }); 
} 

另一個缺點do with是,語法比飛鏢和Smalltalk方法級聯語法更重量級的。更接近於達特風格可能看起來像:

$button_a = GTK::Simple::Button.new(label => 'bcd') 
    ..clicked.tap({ .sensitive = False; $button_b.sensitive = True }); 

回答

2

有了這個子程序:

sub cascade ($obj, &proc) { proc($obj); $obj; } 

的例子可以寫成如下:

use v6; 

use GTK::Simple; 

sub cascade ($obj, &proc) { proc($obj); $obj; } 

GTK::Simple::App.new(title => 'abc').&cascade: { 

    my $app = $_; 

    my $button; 

    .set-content: 
     GTK::Simple::VBox.new(

      GTK::Simple::Button.new(label => 'bcd').&cascade: { 
       .clicked.tap({ .sensitive = False; $button.sensitive = True; }); 
      }; 

      $button = GTK::Simple::Button.new(label => 'cde').&cascade: { 
       .clicked.tap({ $app.exit; }); 
      } 
     ); 

    .border-width = 20; 

    .run; 
}; 
+0

是的。即使你不喜歡運算符名稱'andthen',你是否同意它基本上是''cascade' sub的改進版本? – raiph

+0

@raiph'andthen'不返回「接收對象」。例如,(10然後{20}; 30,然後{40})'返回(20 40)'。而('10.&cascade:{20}; 30.&cascade:{40})'returns'(10 30)'。 – dharmatech

2

我認爲使用given而不是do with對於完全相同的功能更具慣用性。鑑於剛剛通過任何通過作爲主題$_值以下塊。