使用百分号作为前缀运算符名称的一部分

Chr*_*oms 5 function operators perl6

我认为这%ofpercent-of函数名更具可读性和简洁性.这是使用较长名称的工作代码.

#!/bin/env perl6

# Quick stats from gene_exp.diff file

sub percent-of
{
    return sprintf('%.1f', (100 * $^a/ $^b).round(0.1));
}

my $total = first-word-from("wc -l       gene_exp.diff ") -1;  # subtract one for the header
my $ok    = first-word-from "grep -c OK  gene_exp.diff";
my $yes   = first-word-from "grep -c yes gene_exp.diff";

put '| total |    OK | OK % |   yes | yes % | yes / OK |';
put "| $total | $ok | { percent-of $ok, $total } | $yes | { percent-of $yes,$total } | { percent-of $yes, $ok } |";



sub first-word-from ( $command )
{
    return ( qqx{ $command } ).words[0];
}
Run Code Online (Sandbox Code Playgroud)

由于我将子例程名称放在其参数之前,我认为这将是一个前缀运算符.所以这是我认为可以使较短的名称工作(即sub prefix:<%of>用于声明函数):

#!/bin/env perl6

# Quick stats from gene_exp.diff file

sub prefix:<%of>
{
    return sprintf('%.1f', (100 * $^a/ $^b).round(0.1));
}

my $total = first-word-from("wc -l       gene_exp.diff ") -1;  # subtract one for the header
my $ok    = first-word-from "grep -c OK  gene_exp.diff";
my $yes   = first-word-from "grep -c yes gene_exp.diff";

put '| total |    OK | OK % |   yes | yes % | yes / OK |';
put "| $total | $ok | { %of($ok, $total) } | $yes | { %of($yes,$total) } | { %of($yes,$ok) } |";

sub first-word-from ( $command )
{
    return ( qqx{ $command } ).words[0];
}
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

| total |    OK | OK % |   yes | yes % | yes / OK |
Too few positionals passed; expected 2 arguments but got 1
  in sub prefix:<%of> at /home/bottomsc/bin/gene_exp_stats line 6
  in block <unit> at /home/bottomsc/bin/gene_exp_stats line 15
Run Code Online (Sandbox Code Playgroud)

我确信我正在尝试的东西是可能的.我看到比这更疯狂的功能,就像我不关心运算符¯\(°_o)/¯的中缀.我究竟做错了什么?在尝试%of使用和不使用括号进行调用时,我得到完全相同的错误,因此这不是问题.

在我输入这个问题的时候,我刚刚意识到我应该尝试按照刚引用例子来做这个作为中缀运算符并且它有效.但是,我仍然很好奇为什么我的前缀操作符代码不起作用.这可能是我忽略的非常基本的东西.


更新:

这是作为中缀运算符完成的工作代码.但我仍然对前缀版本的错误感到好奇:

#!/bin/env perl6

# Quick stats from gene_exp.diff file

sub infix:<%of>
{
    return sprintf('%.1f', (100 * $^a/ $^b).round(0.1));
}

my $total = first-word-from("wc -l       gene_exp.diff ") -1;  # subtract one for the header
my $ok    = first-word-from "grep -c OK  gene_exp.diff";
my $yes   = first-word-from "grep -c yes gene_exp.diff";

put '| total |    OK | OK % |   yes | yes % | yes / OK |';
put "| $total | $ok | { $ok %of $total } | $yes | { $yes %of $total } | { $yes %of $ok } |";

sub first-word-from ( $command )
{
    return ( qqx{ $command } ).words[0];
}
Run Code Online (Sandbox Code Playgroud)

sml*_*mls 6

使用两个参数调用前缀op

左括号仅在函数名称后面被解释为函数调用,而不是在它跟在前缀运算符名称之后.

因此,在你的第二个代码片段,这种表达就不会调用%of使用两个参数操作:

%of($ok, $total)
Run Code Online (Sandbox Code Playgroud)

相反,它创建一个List带有两个元素的值,然后将%of运算符应用于该单个List值 - 因此出现错误消息" expected 2 arguments but got 1".

为了将多个参数传递给前缀运算符,您必须调用其完全限定名称:

prefix:<%of>($ok, $total);
Run Code Online (Sandbox Code Playgroud)

当然这会否定你的"可读和简洁"的目标.

使用单个参数

如果您真的想为此使用前缀运算符,则可以使其接受单个List参数,并使用子签名将其解压缩到签名中的两个值[ ]:

sub prefix:<%of> ([$a, $b]) {
    sprintf '%.1f', (100 * $a / $b).round(0.1);
}

say %of(42, 50);  # 84.0
Run Code Online (Sandbox Code Playgroud)

忠告

请注意,声明一个看起来像哈希变量的运算符可能会让下一个必须维护代码的人感到困惑(甚至可能是你自己,当你几周后回到它时).

内置前缀运算符喜欢++~限制自己使用一个或两个非字母符号,这是有充分理由的.Perl 6对用户定义的运算符没有相同的限制,但请记住,强大的功能带来了很大的责任...... :)


Mat*_*tes 5

我认为%对于函数名称来说,它的可读性和简洁性比%.

非常不同意,因为这看起来完全像哈希印记.如果我和你一起工作,如果我碰到这个,我会发疯的.出了什么问题percent-of中缀?5 percent-of 100返回0.05还是什么?

我读了%of of hash.从来没有百万年读Perl时我会认为%是一个新定义的运算符,意思是"百分比"这样的前缀.因此,鉴于语言,它是不可读的.它简洁并不是一个很好的理由,它具有更大的认知负荷,因此再次不太可读.我不完全确定批评的平衡是什么?除了它的可怕和酷,你可以做到这一点......

  • 正是我需要听到的.我100%同意你的意见.因为没有考虑可维护性而感到有点惭愧.我认为这正是拉里·沃尔所说的那种东西,当他说用Perl 6时我们得到了"足够的绳索射击自己的脚". (2认同)