方法级联语法

时间:2016-06-01 05:08:12

标签: perl6

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 });
    $_
}

如果不必明确地返回$_,那将是很好的。例如,像:

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

do with的另一个缺点是语法比Dart和Smalltalk方法级联语法更重要。更接近Dart风格的东西可能如下:

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

3 个答案:

答案 0 :(得分:4)

https://doc.perl6.org/routine/andthen

my $obj = IO::Path.new($*CWD) andthen do { .say; 42 }; say $obj.perl

答案 1 :(得分: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;
};

答案 2 :(得分:2)

我认为使用given而不是do with对于完全相同的功能更为惯用。给定只是通过任何通过作为下一个块的主题$_值。