小编Eri*_*rom的帖子

你能在Pe​​rl中引用内置函数吗?

什么语法,如果有的话,能够引用内置的像shift

$shift_ref = $your_magic_syntax_here;
Run Code Online (Sandbox Code Playgroud)

您可以使用与用户定义的子相同的方式:

sub test { ... }

$test_ref = \&test;
Run Code Online (Sandbox Code Playgroud)

我尝试了以下,但都不起作用:

\&shift
\&CORE::shift
\&{'shift'}
\&{'CORE::shift'}
Run Code Online (Sandbox Code Playgroud)

如果需要,你的答案可以包括XS,但我不愿意.

澄清:我正在寻找一种通用解决方案,可以从任何内置程序获得功能齐全的代码参考.然后可以将此coderef传递给任何更高阶的函数,就像对用户定义的子的引用一样.到目前为止似乎是共识,这是不可能的,任何人都不同意?

syntax perl

14
推荐指数
1
解决办法
1275
查看次数

在Perl模块中检查无穷大的最佳方法是什么?

在我的一个模块中,我必须处理无限的概念.到目前为止,我一直在使用9**9**9正无穷大,这似乎运作良好,速度快,似乎是perl的内部用作无限.

但是,如果我的模块的用户决定使用其中一个大数字模块(例如use bigint;),然后他们使用infMath::BigInt->binf()表示无穷大,事情会有点冒险.

在某些地方它似乎工作正常,但在其他地方,比较应该是真的或应该是错误的最终错误的方式导致难以追踪错误.

我想支持无限的其他各种概念,它们可以使用普通的perl数和任意精度数.

但我也对性能表示担忧,因为我对无穷大的一些比较发生在紧密的内环中.显然,inffrom Math::BigInt会慢于9**9**9(由于在每次访问时调用绑定或重载方法).过去有没有人处理过这个问题?如果是这样,你的解决方案是什么?

我已经考虑过将自己的常量用于无穷大,定义如下:

use constant INF => if_any_bignum_modules_loaded() 
                    ? Math::BigInt->binf 
                    : 9**9**9;
Run Code Online (Sandbox Code Playgroud)

然后向我的模块添加警告,首先应该加载任何bignum模块.这听起来合情合理吗?是否有可靠的实施if_any_bignum...,或者我应该自己推出?

perl module biginteger bignum infinity

13
推荐指数
1
解决办法
659
查看次数

如何在Perl 6中返回上下文敏感的返回值?

在Perl 5和Perl 6之间差异的总结中,注意到该wantarray功能已经消失:

wantarray()走了

wantarray走了.在Perl 6中,上下文向外流动,这意味着例程不知道它在哪个上下文中.

相反,你应该返回在每个上下文中做正确事情的对象.

有人可以举例说明如何创建这样的对象吗?

perl perl6 perl5 raku

13
推荐指数
1
解决办法
419
查看次数

为什么Perl发出的"使用"转移"没有括号"是一个含糊不清的警告?

有没有人知道什么解析或优先级决定导致警告'使用'shift"没有括号是不明确的'为代码发出,如:

shift . 'some string';

# and not

(shift) . 'some string'; # or
shift() . 'some string';
Run Code Online (Sandbox Code Playgroud)

这是否有意使某些句法结构更容易?或者它只是perl解析器工作方式的工件?

注意:这是关于语言设计的讨论,而不是建议的地方

"@{[shift]}some string"
Run Code Online (Sandbox Code Playgroud)

syntax perl warnings

12
推荐指数
2
解决办法
3150
查看次数

在有限的资源设备上加快CPAN的技巧是什么?

我最近尝试在我的手机(诺基亚n900)上升级一些Perl模块,并安装最新版本的Module::Build一小时.

大多数情况下(70%)似乎花费在解析和索引存储库信息上.

似乎有一些选项,例如每次都不重建索引缓存,或者使用CPAN :: SQLite.

我想继续在设备上使用CPAN,而不是手动安装模块.所以我想知道人们在类似的有限资源设备上取得了哪些成功(缓慢的CPU,有限的RAM,慢速磁盘(闪存))?

perl cpan

10
推荐指数
1
解决办法
1226
查看次数

在Perl中,创建一个与包名称相同的子例程有什么危害吗?

假设我有一个名为的包My::Pkg,并且该包有一个->new(...)类方法来实例化新对象:

package My::Pkg;

sub new {bless {@_[1..$#_]} => $_[0]}
Run Code Online (Sandbox Code Playgroud)

定义以下子例程有什么危害:

sub My::Pkg {@_ ? My::Pkg::new('My::Pkg', @_) : 'My::Pkg'}
Run Code Online (Sandbox Code Playgroud)

所以有人可以写:

my $obj = My::Pkg one => 1, two => 2;
Run Code Online (Sandbox Code Playgroud)

而不是:

my $obj = My::Pkg->new(one => 1, two => 2); # which still works, but is longer
Run Code Online (Sandbox Code Playgroud)

我喜欢package-named-constructor-subroutine方法的简洁性,但我很想知道这个技术是否有任何隐藏的问题,我没有想到.


更新:

继承正常工作,如下例所示:

{package a; sub new {say "a::new [@_] ", $_[0]->init}}
{package b;    our @ISA = 'a'; sub init {"(b::init [@_])"}}
{package a::b; our @ISA = 'b';}

sub a::b …
Run Code Online (Sandbox Code Playgroud)

syntax perl constructor

10
推荐指数
1
解决办法
220
查看次数

在Perl中,确定coderef包的最可靠方法是什么?

我有许多高阶实用程序函数,它们接受代码引用并将该代码应用于某些数据.其中一些函数需要在执行子例程期间本地化变量.开始时,我正在使用caller以与此示例reduce函数中所示类似的方式确定要本地化的包:

sub reduce (&@) {
    my $code      = shift;
    my $caller    = caller;
    my ($ca, $cb) = do {
        no strict 'refs';
        map \*{$caller.'::'.$_} => qw(a b)
    };
    local (*a, *b) = local (*$ca, *$cb);
    $a = shift;
    while (@_) {
        $b = shift;
        $a = $code->()
    }
    $a
}
Run Code Online (Sandbox Code Playgroud)

最初这种技术运行良好,但是当我尝试围绕高阶函数编写包装函数时,找出正确的调用者变得复杂.

sub reduce_ref (&$) {&reduce($_[0], @{$_[1]})}
Run Code Online (Sandbox Code Playgroud)

现在为了reduce工作,我需要这样的东西:

    my ($ca, $cb) = do {
        my $caller = 0;
        $caller++ while caller($caller) =~ /^This::Package/;
        no strict …
Run Code Online (Sandbox Code Playgroud)

perl higher-order-functions

10
推荐指数
1
解决办法
481
查看次数

为什么这个anon子例程声明在Perl中被解析为间接对象方法?

在下面的匿名子例程声明中,Perl似乎将其解析为间接方法调用,而不是作为子例程:

use 5.010;
use strict;
use warnings;

sub proxy {
    my $new = shift;
    say "creating proxy: $new";
    sub :lvalue {
        say "running proxy: $new";
        tie my $ret, 'Some::Package', shift, $new;
        $ret
    }
}

say "before";
my $p1 = proxy '_value';
say "p1 declared: $p1";
my $p2 = proxy 'value';
say "p2 declared: $p2";
Run Code Online (Sandbox Code Playgroud)

打印:

before
creating proxy: _value
running proxy: _value
Can't locate object method "TIESCALAR" via package "Some::Package" ...

如果a return或者my $sub =之前添加sub :lvalue …

syntax perl anonymous-function

9
推荐指数
1
解决办法
193
查看次数

在Perl中,为什么绑定数组这么慢?

在我的测试中,我注意到迭代绑定数组的速度最好是使用内部存取方法(FETCHFETCHSIZE)的一半.以下基准显示了该问题:

{package Array;
    sub new {
        my $class = shift;
        tie my @array, $class, [@_];
        \@array
    }
    sub TIEARRAY {
        my ($class, $self) = @_;
        bless $self => $class;
    }
    sub FETCH     {$_[0][$_[1]]}
    sub FETCHSIZE {scalar @{$_[0]}}
}

use List::Util 'sum';
use Benchmark 'cmpthese';

for my $mag (map 10**$_ => 1 .. 5) {

    my $array = Array->new(1 .. $mag);
    my $tied  = tied(@$array);
    my $sum   = sum @$array;

    print "$mag: \n";
    cmpthese -2 => { …
Run Code Online (Sandbox Code Playgroud)

perl performance

8
推荐指数
2
解决办法
933
查看次数

在Perl中,有没有办法打破藏匿?

类似于AUTOLOAD可以根据需要定义子例程的方式,我想知道是否有办法绑定一个包的存储,以便我可以拦截对该包中变量的访问.

我尝试了以下想法的各种排列,但似乎都没有效果:

{package Tie::Stash;
    use Tie::Hash;
    BEGIN {our @ISA = 'Tie::StdHash'}
    sub FETCH {
        print "calling fetch\n";
    }
}

{package Target}

BEGIN {tie %Target::, 'Tie::Stash'}

say $Target::x;  
Run Code Online (Sandbox Code Playgroud)

Bad symbol for scalar ...在最后一行死亡,没有打印"calling fetch".如果say $Target::x;删除该行,程序将运行并正确退出.

我的猜测是失败与stashes有关,但与散列不一样,所以标准的tie机制不能正常工作(或者它可能就是stash lookup永远不会调用tie魔法).

有谁知道这是否可能?Pure Perl是最好的,但XS解决方案还可以.

perl tie perl-stash

8
推荐指数
1
解决办法
281
查看次数