Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中将闭包作为句柄打开_Perl_Closures_Handles - Fatal编程技术网

在Perl中将闭包作为句柄打开

在Perl中将闭包作为句柄打开,perl,closures,handles,Perl,Closures,Handles,所以我有一个疯狂的想法。现在,我正在Word中使用Text::csvxs生成一个表,如下所示: use Win32::OLE; use Win32::OLE::Const 'Microsoft Word'; use Text::CSV_XS; # instantiation of word and Text::CSV_XS omitted for clarity my $select = $word->Selection; foreach my $row (@rows) { # @row

所以我有一个疯狂的想法。现在,我正在Word中使用Text::csvxs生成一个表,如下所示:

use Win32::OLE;
use Win32::OLE::Const 'Microsoft Word';
use Text::CSV_XS;

# instantiation of word and Text::CSV_XS omitted for clarity
my $select = $word->Selection;
foreach my $row (@rows) { # @rows is an array of arrayrefs
    $csv->combine(@{$row});
    $select->InsertAfter($csv->string);
    $select->InsertParagraphAfter;
}
$select->convertToTable(({'Separator' => wdSeparateByCommas});
但如果我能做这样的事情会更酷:

use Win32::OLE;
use Win32::OLE::Const 'Microsoft Word';
use Text::CSV_XS;

# instantiation of word and Text::CSV_XS omitted for clarity
my $select = $word->Selection;
foreach my $row (@rows) { # @rows is an array of arrayrefs
    $csv->bind_columns($row);
    $csv->print( 
        sub {
            my $something; # Should be the combine()'d string
            $select->InsertAfter($something);
            $select->InsertParagraphAfter;
        },
        undef
    ); 
}
$select->convertToTable(({'Separator' => wdSeparateByCommas});

那么,我的问题是如何从我的第二个代码示例中获得
$something
,以及我需要做什么才能使闭包看起来像一个句柄?

Text::CSV::print
不一定需要句柄。文档只是说它需要一个
print
方法

{
    package Print::After::Selection;
    sub new {
        my ($pkg, $selection) = @_;
        my $self = { selection => $selection };
        return bless $self, $pkg;
    }
    sub print {
        my ($self, $string) = @_;
        my $selection = $self->{selection};
        $selection->InsertAfter($string);
        $selection->InsertParagraphAfter;
        return 1;  # return true or Text::CSV will think print failed
    }
}

...
$csv->print( Print::After::Selection->new( $word->Selection ), undef );
...

(未经测试)

我相信您实际上是在问如何使用以下界面将数据转换成Word:

my $fh = SelectionHandle->new($selection);
my $csv = Text::CSV_XS->new({ binary => 1 });
$csv->print($fh, $_) for @rows;
(我认为这是个坏主意。它是由内而外的。创建一个使用封装的CSV对象格式化的对象。)

如果你想给一个对象一个变量接口(标量、数组、散列、文件句柄),你需要
tie
。当你这样做的时候,你最终会

use SelectionHandle qw( );
use Text::CSV_XS    qw( );

my $selection = ...;
my @rows      = ...;

my $fh = SelectionHandle->new($selection);
my $csv = Text::CSV_XS->new({ binary => 1 });
$csv->print($fh, $_) for @rows;
这个模块看起来像:

package SelectionHandle;

use strict;
use warnings;

use Symbol      qw( gensym );
use Tie::Handle qw( );

our @ISA = qw( Tie::Handle );

sub new {
   my ($class, $selection) = @_;
   my $fh = gensym();
   tie(*$fh, $class, $selection);
   return $fh;
}

sub TIEHANDLE {
   my ($class, $selection) = @_;
   return bless({
      selection => $selection,
   }, $class);
}

sub PRINT {
   my ($self, $str) = @_;
   my $selection = $self->{selection};
   $selection->InsertAfter($str);
   $selection->InsertParagraphAfter();
   return 1;
}

1;

我想知道,有没有办法创建一个匿名对象来实现这一点?@Kit Peters,你是说匿名类,而Perl还没有。你在某种程度上是对的,我把两个问题合并成一个问题是错误的。最终,我确实希望这些数据以Word结尾,但我想知道我是否可以创建某种匿名类-在本例中,类似于带有print()方法的闭包-我可以将特定于Word的代码封装在其中。我可以从技术上更改我的类,使其构造函数接受闭包
my$fh=callback_handle{…打印时调用的代码…}