0

我们正在尝试构建一个 API 来自动支持 commit() 和 rollback(),这样我们就不必再为它烦恼了。通过研究,我们发现使用eval {}是要走的路。

为了eval {}知道该怎么做,我想给 API 一个函数数组,它可以用 a 来执行,foreach而无需 API 解释任何东西。但是,此函数可能位于不同的包中。

让我用一个例子来澄清:

sub handler {
    use OSA::SQL;
    use OSA::ourAPI;
    my @functions = ();
    push(@functions, OSA::SQL->add_page($date, $stuff, $foo, $bar));
    my $API = OSA::ourAPI->connect();
    $API->exec_multi(@functions);
}

问题是:即使 ourAPI@functions没有. 如果不是,是否可以使用数组引用而不是数组,因为指针将指向内存中的已知函数?OSA::ourAPIuse OSA::SQL

注意:这是我们想要基于更复杂的最终版本的基本思想。

4

1 回答 1

4

  • 您没有向数组添加函数指针。您正在添加调用 add_page() 子例程的返回值。您对此有 3 个解决方案:

    A. 您将需要存储 (in @functions) 形式的 arrayrefs 数组[\&OSA::SQL::add_page, @argument_values],这意味着您传入对子例程的实际引用(静态调用);然后 exec_multi 会做类似的事情(语法可能不是 100% 正确,因为这里是凌晨 4 点)

    子 exec_multi {
        我的 ($class, $funcs)= @_;
        foreach 我的 $f (@$funcs) {
            我的 ($func, @args) = @$f;
            我的 $res = &$func(@args);
            打印 "RES:$res\n";
        }
    }
    

    只是为了重新迭代,这将调用静态版本 ( OSA::SQL::add_page) 中的各个 subs,例如,不会像类调用那样将包名称作为第一个参数传递OSA::SQL->add_page。如果您想要后者,请参阅下一个解决方案。


    B. 如果您想在类上下文中调用您的 subs(如在您的示例中,换句话说,将类名作为第一个参数),您可以在评论中使用 ysth 的建议。

    您将需要存储 (in @functions) 形式的 arrayrefs 数组[sub { OSA::SQL->add_page(@argument_values) }],这意味着您传入对子例程的引用,该子例程将依次调用您需要的内容;然后 exec_multi 会做类似的事情(语法可能不是 100% 正确,因为这里是凌晨 4 点)

    子 exec_multi {
        我的 ($class, $funcs)= @_;
        foreach 我的 $f (@$funcs) {
            我的 ($func) = @$f;
            我的 $res = &$func();
            打印 "RES:$res\n";
        }
    }
    

    C. 您将需要存储(in @functions)形式的 arrayrefs 数组[ "OSA::SQL", "add_page", @argument_values],这意味着您传入一个包和函数名称;然后 exec_multi 会做类似的事情(语法可能不是 100% 正确,因为这里是凌晨 4 点)

    我的 ($package, $sub, @args) = @{ $functions[$i] };
    没有严格的“参考”;
    $package->$sub(@args);
    使用严格的“参考”;
    

  • 如果我正确理解了您的问题,那么您无需担心 ourAPI 是否使用 OSA::SQL,因为您的主代码已经导入了它。

    但是,由于 - 在 #1B 中 - 您将把一个包列表作为每个 arrayref 的第一个元素传递给 exec_multi,因此您可以require $package; $package->import();在 exec_multi 中执行“”。但是同样,如果您的处理程序调用已经需要并加载了这些包中的每一个,则完全没有必要。要做到这一点,您还需要将参数列表传递给import()。但是为什么?:)

于 2010-08-04T07:38:18.150 回答