Hash 这是Perl 6哈希还是块?

Hash 这是Perl 6哈希还是块?,hash,block,raku,Hash,Block,Raku,这是一种意想不到的行为,可能会伤害初学者。首先,这是有意的吗?第二,Perl 6还使用哪些其他东西来猜测要创建哪个对象?它一开始是认为它是块还是散列,然后再更改,还是最终决定 您可以使用大括号和胖箭头构造一个: my $color-name-to-rgb = { 'red' => 'FF0000', }; put $color-name-to-rgb.^name; # Hash 使用另一对表示法也会创建一个 但是,如果没有胖箭,我会得到一个: 文档中只提到在大括号内使

这是一种意想不到的行为,可能会伤害初学者。首先,这是有意的吗?第二,Perl 6还使用哪些其他东西来猜测要创建哪个对象?它一开始是认为它是块还是散列,然后再更改,还是最终决定

您可以使用大括号和胖箭头构造一个:

my $color-name-to-rgb = {
    'red' => 'FF0000',
    };

put $color-name-to-rgb.^name;  # Hash
使用另一对表示法也会创建一个

但是,如果没有胖箭,我会得到一个:

文档中只提到在大括号内使用
$\uu
会创建一个

还有其他定义散列的方法,但我只是询问这一特定的语法,而不是寻找我已经知道的解决方法

$ perl6 -v
This is Rakudo version 2017.04.3 built on MoarVM version 2017.04-53-g66c6dda
implementing Perl 6.c.
当它是一个
散列时
您的问题1和此答案仅适用于术语位置2中的支撑块

完全遵循下面解释的规则的大括号代码构造一个
散列

say WHAT {                  }             # (Hash)
say WHAT { %foo             }             # (Hash)
say WHAT { %foo, ...        }             # (Hash)
say WHAT { foo => 42, ...   }             # (Hash)
say WHAT { :foo, ...        }             # (Hash)
say WHAT { key => $foo, ... }             # (Hash)
规则 如果块是空的,或者只包含一个列表,其第一个元素是
%
符号变量(例如
%foo
)或文本对(例如
:bar
),并且没有签名或包含顶级语句,那么它就是
哈希。否则它就是一个

强制
散列
解释
  • 要强制
    {…}
    术语构造
    而不是
    散列
    ,请编写
    {;..}

  • 要写入空的
    项,请写入
    {;}

  • 要编写空的
    散列
    术语,请编写
    {}

  • 要强制
    {…}
    术语构造
    散列
    而不是
    ,请遵循规则(在本答案的其余部分中详细解释),或者改为写入
    %(…)

显式签名表示它是
某些带大括号的代码具有显式签名,即它具有显式参数,如下面的
$foo
。它总是构造一个
,无论大括号内有什么:

say WHAT         { key => $foo, 'a', 'b' } # (Hash)
say WHAT -> $foo { key => $foo, 'a', 'b' } # (Block)
say WHAT { key => $_ }                     # (Block)
say WHAT { key => 'value', .foo, .bar }    # (Block)
隐式签名也意味着它是
某些带大括号的代码有一个隐式签名,该签名是由于块内某些显式编码选择而生成的:

  • {…}
    中使用“代词”意味着它是带有签名的
    (如果它还没有显式签名,则为隐式签名)。代词是
    $\u
    @
    %\u

  • 这包括在
    {…}
    内部由于没有左侧参数的
    .method
    调用而隐含使用
    $\uu
    。换句话说,由于
    .foo
    缺少左侧参数,即使
    {.foo}
    也有签名(
    (;;$是原始的)

  • 使用“占位符”变量(例如
    $^foo

与显式签名一样,如果大括号代码具有隐式签名,则无论大括号内有什么内容,它都会构造一个

say WHAT         { key => $foo, 'a', 'b' } # (Hash)
say WHAT -> $foo { key => $foo, 'a', 'b' } # (Block)
say WHAT { key => $_ }                     # (Block)
say WHAT { key => 'value', .foo, .bar }    # (Block)
顶级语句表示它是一个
第二行包含多个语句,但它们在作为单个顶级表达式的列表的各个元素中生成值

标识符的顶级声明表示它是
声明是一种声明,但我已经包括了这一部分,以防有人没有意识到这一点

say WHAT { :foo, $baz, {my $bar} }        # (Hash)
say WHAT { :foo, $baz, (my $bar) }        # (Block)
第一行包含一个
,作为包含声明的键(
my$bar
)。但是该声明属于内部
{my$bar}
,而不是外部
{…}
。因此,就外部
{…}
而言,内部
只是一个值,因此外部带括号的代码仍然被解释为
散列

相反,第二行直接在外部
{…}
中声明一个变量。所以它是一个

仍然
Block
s,而不是
Hash
s 回想一下,要成为
散列
,大括号代码的内容必须是以
%
符号变量或文本对开头的列表。因此,所有这些都会产生
Block
s:

my $bar = key => 'value';
say WHAT { $bar, %baz }                   # (Block)
say WHAT { |%baz      }                   # (Block)
say WHAT { %@quux     }                   # (Block)
say WHAT { 'a', 'b', key => $foo }        # (Block)
say WHAT { Pair.new: 'key', $foo }        # (Block)
脚注 1这个“
散列
?”问题就是设计的一个例子。在Raku文化中,良好的DWIM设计被认为是一件好事。但是每个DWIM都有相应的WATs3。良好DWIM设计的关键是确保WATs’4;树皮是有用的;人们认为DWIM的净效益远远超过了所有的吠叫和咬人行为

术语是英语中名词或名词短语的类似词。这是一个价值观

作为术语的支撑块示例:

.say given { ... }  # closure? hash?
say 42, { ... }     # closure? hash?
非术语的支撑块示例:

此答案仅讨论作为术语的大括号块。有关术语的更多详细信息,或者更具体地说是“术语位置”(语法中带括号的块将被解释为术语的位置),请参见此答案下面的注释

3指的是当某件事情在他们看来很疯狂时,开发人员难以置信的惊讶。众所周知,即使对于精心设计的DWIM,对于大多数人来说,在大多数时间,都不可避免地会有一个或多个相关的WAT让一些人感到惊讶,有些时候,包括一些在其他时间受益于DWIM的相同的人

4与此DWIM相关的水的咬合程度各不相同。这通常是一个吠叫(错误消息),使问题显而易见。但它也可能更加模糊:

say { a => 42 }() ;  # No such method 'CALL-ME' for invocant of type 'Hash'   WAT? Oh.
say { a => $_ }<a> ; # Type Block does not support associative indexing.      WAT? Oh.

say { a => $_, b => 42, c => 99 } .elems  # 1                                 WAT?????
说{a=>42}();#对于“Hash”WAT类型的发票,没有这样的方法“CALL-ME”?哦
说{a=>$\}

6社区成员对DWIM总体设计或任何特定的DWIM设计是否值得持有不同意见。cf与Sam对此问题的回答。

首选的Per
if True { ... }     # always a closure
class foo { ... }   # always a package
put bar{ ... }      # always a hash index
say { a => 42 }() ;  # No such method 'CALL-ME' for invocant of type 'Hash'   WAT? Oh.
say { a => $_ }<a> ; # Type Block does not support associative indexing.      WAT? Oh.

say { a => $_, b => 42, c => 99 } .elems  # 1                                 WAT?????
my $color-name-to-rgb = %(
    'red', 'FF0000',
    );