2

我一直在修改将 IPC 机制的一些实现细节隐藏在绑定数组后面的想法。目标是能够在服务器端做这样的事情:

# setup code here. Client provides a function name, we find
# a function to deal with the request:
my $coderef = lookup($method);
local @_;
tie @_, 'My::IPC';
@ret = &$coderef;

然后,My::IPC该类将根据需要从管道/套接字读取序列化对象(通过SHIFTorFETCH 方法触发)。

我想为服务器函数的作者提供一些方法来编写他的 IPC 可访问函数,而他会编写本地函数,即:

sub f1 {
    while (my $param = shift) {
        ...
    }
}

... 也 ...

sub f2 {
    my ($foo, $bar, $baz, %flags) = @_;
    ...
}

f1旨在能够处理可能大于可用 RAM 量的数据流——只要每个单独的对象在反序列化后适合 RAM,一切都很好。f2 用于“更简单”的函数,其中参数列表可以被吞入 RAM。

为了支持这两种情况,需要实现TIEARRAY构造函数和SHIFT, FETCHFETCHSIZE方法。我认为那部分解决了。困扰我的是,我似乎找不到让我undef将值传输到的方法,f1因为即使在列表上下文中,在空数组上使用时也会shift返回。undef就像是

@params = splice @_, 0, 1;

可能在这里工作,但这并不完全像用户的明显解决方案。

只要有可用的数据,我可以通过对它进行轻微修改f1并以它返回 1 的方式实现来解决这个问题:FETCHSIZE

sub f3 {
    while (@_) {
        my $param = shift;
        ...
    }
}

但这会中断f2,因为只有第一个元素会被分配。显然,FETCHSIZE需要提供准确的值,但要获得准确的值,需要将整个数组放入 RAM 中——这违背了迭代它的目的。

有没有一种优雅的方式来支持“流”模型(f1, f3)和更简单的类似函数调用的模型(f2)具有相同的绑定数组实现?

4

1 回答 1

5

数组有长度。如果你的代码不能像数组一样工作,那么给它一个数组的接口就不是一个好主意。

您可以使用获取基础对象tied

sub f1 {
   while ( my ($param) = tied(@_)->next() ) {
      ...
   }
}

sub f2 {
   my ($foo, $bar, $baz, %flags) = @_;
   ...
}

但是最好避免绑定不是数组的东西。

sub f1 {
   my $o = shift;
   while ( my ($param) = $o->next ) {
      ...
   }
}

sub f2 {
   my ($foo, $bar, $baz, %flags) = shift->all;
   ...
}

请注意,它next是在列表上下文中调用的,因此除了返回 undef 之外,它还可以选择返回一个空列表,从而可以将迭代的结束与undef.

于 2013-09-26T19:27:58.340 回答