Perl 6块是一个参数还是没有? [英] Is that one argument or none for a Perl 6 block?

查看:76
本文介绍了Perl 6块是一个参数还是没有?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在没有显式签名的块中,用Perl 6区分参数和无参数的区别是什么?我对此没有任何实际用途,但我很好奇.

What is the Perl 6 way to tell the difference between an argument and no argument in a block with no explicit signature? I don't have any practical use for this, but I'm curious.

没有显式签名的块会将值放入$_:

A block with no explicit signature puts the value into $_:

my &block := { put "The argument was $_" };

签名实际上是;; $_? is raw.这是一个可选参数.在该块中未定义@_变量,因为没有显式签名.

The signature is actually ;; $_? is raw. That's one optional argument. The @_ variable isn't defined in the block because there is no explicit signature.

有no参数,其中$_将是未定义的:

There's the no argument, where $_ will be undefined:

&block();  # no argument

但是还有一种情况,其中$_将是不确定的.类型对象始终是未定义的:

But there's also a one argument situation where $_ will be undefined. A type object is always undefined:

&block(Int);

但是,没有任何内容的$_实际上是任何(而不是(例如).我无法分辨这两种情况之间的区别:

But, an $_ with nothing in it is actually an Any (rather than, say, Nil). I can't tell the difference between these two cases:

&block();
&block(Any);

这是一个更长的例子:

my $block := {
    say "\t.perl is {$_.perl}";

    if $_ ~~ Nil {
        put "\tArgument is Nil"
        }
    elsif ! .defined and $_.^name eq 'Any' {
        put "\tArgument is an Any type object"
        }
    elsif $_ ~~ Any {
        put "\tArgument is {$_.^name} type object"
        }
    else {
        put "\tArgument is $_";
        }
    };

put "No argument: ";    $block();
put "Empty argument: "; $block(Empty);
put "Nil argument: ";   $block(Nil);
put "Any argument: ";   $block(Any);
put "Int argument: ";   $block(Int);

请注意,no参数和Any参数形式显示相同的内容:

Notice the no argument and Any argument forms show the same things:

No argument:
    .perl is Any
    Argument is an Any type object
Empty argument:
    .perl is Empty
    Argument is Slip type object
Nil argument:
    .perl is Nil
    Argument is Nil
Any argument:
    .perl is Any
    Argument is an Any type object
Int argument:
    .perl is Int
    Argument is Int type object

推荐答案

这是我解决此问题的方法.我很想以一种更简洁的方式来做到这一点,但是语言的聪明才智却阻碍了我的工作.这适用于位置参数,但对于命名参数有更深的含义,在这里我将不再处理.

Here's how I solved this. I'd love to do this in a cleaner way but the cleverness of the language gets in the way and I have to work around it. This works for positional parameters but there are deeper shenanigans for named parameters and I won't deal with those here.

我还有一个问题,为什么将Perl 6命名参数限制为确定值,为什么将其作为必需值? ,答案明确表明实际上没有可选参数.只有参数具有默认值,如果我未明确分配参数,则存在隐式默认值.

I had another question, Why does constraining a Perl 6 named parameter to a definite value make it a required value?, where the answers clarified that there are actually no optional parameters. There are merely parameters that have a default value and that there is an implicit default value if I don't explicitly assign one.

问题的症结在于,我想知道何时给参数赋值,以及何时不给参数赋值.我通过一个参数或一个显式的默认值给它一个值.隐式默认值是正确类型的类型对象.如果我未指定类型,则为Any.该隐式默认值必须满足我指定的任何约束.

The crux of my problem is that I want to know when I gave the parameter a value and when I didn't. I give it a value through an argument or an explicit default. An implicit default is a type object of the right type. That's Any if I didn't specify a type. That implicit default must satisfy any constraint I specify.

第一个目标是严格限制用户在调用代码时可以提供的值.如果未定义的值无效,则不应允许它们指定一个.

The first goal is to tightly constrain the values a user can supply when they call code. If an undefined value is not valid then they shouldn't be allowed to specify one.

第二个目标是轻松区分代码中的特殊情况.我想减少一些更深层次的代码需要知道的特殊知识.

The second goal is to easily distinguish special cases in the code. I want to reduce the amount of special knowledge some part of the deeper code needs to know.

我可以通过显式分配一个我知道不会有任何其他意义的特殊值来获得第三种情况(其中我知道没有参数或合适的默认值).有一个值甚至比Any毫无意义.那是Mu.它是所有未定义值中最不确定的值. AnyMu的两个子类型之一(另一个是Junction),但是您几乎永远不会看到Mu以普通代码出现在您的一个值中.用户代码中未定义的内容始于Any.

I can get the third case (where I know there was no argument or suitable default) by explicitly assigning a special value that I know can't be anything other meaningful thing. There's a value that's even more meaningless than Any. That's Mu. It's the most undefined values of all undefined values. The Any is one of two subtypes of Mu (the other is Junction) but you should almost never see a Mu end up in one of your values in normal code. Undefined things in user code start at Any.

我可以创建一个约束来检查我想要的类型或Mu并将默认值设置为Mu.如果我看到Mu,我知道没有参数,而它是Mu,因为我的约束设置了该参数.

I can create a constraint that checks for the type I want or for Mu and set a default of Mu. If I see a Mu I know there was no argument and that it's Mu because my constraint set that.

由于我正在使用Mu,因此有些事情我无法执行,例如使用===运算符.智能匹配不起作用,因为我不想测试继承链.我可以直接检查对象名称:

Since I'm using Mu there are some things I can't do, like use the === operator. Smart matching won't work because I don't want to test the inheritance chain. I can check the object name directly:

my $block := ->
    $i where { $^a.^name eq 'Mu' or $^a ~~ Int:D } = Mu
    {
    say "\t.perl is {$i.perl}";

    put do given $i {
        when .^name eq 'Mu'  { "\tThere was no argument" }
        when Nil             { "\tArgument is Nil"       }
        when (! .defined and .^name eq 'Any') {
            "\tArgument is an Any type object"
            }
        when .defined {
            "\tArgument is defined {.^name}"
            }
        default { "\tArgument is {.^name}" }
        }
    };

put "No argument: ";         $block();
put "Empty argument: ";      try $block(Empty); # fails
put "Nil argument: ";        try $block(Nil);   # fails
put "Any type argument: ";   try $block(Any);   # fails
put "Int type argument: ";   try $block(Int);   # fails
put "Int type argument: ";   $block(5);

现在大多数此类调用失败,因为它们未指定正确的内容.

Now most of those invocations fail because they don't specify the right things.

如果这些是例行程序,我可以在少数情况下进行多次乘数运算,但最终这是一个更糟糕的解决方案.如果我有两个参数,则需要四个乘法.使用三个这样的参数,我需要六个.那是很多样板代码.但是,块不是例程,因此在这里无济于事.

If these were routines I could make multis for a small number of cases but that's an even worse solution in the end. If I had two parameters I'd need four multis. With three such parameters I'd need six. That's a lot of boilerplate code. But, blocks aren't routines so that's moot here.

这篇关于Perl 6块是一个参数还是没有?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆