在Perl中将闭包作为句柄打开
所以我有一个疯狂的想法。现在,我正在Word中使用Text::csvxs生成一个表,如下所示:在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
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{…打印时调用的代码…}代码>