创建Perl函数,接受内置打印等可选文件句柄?

时间:2018-01-10 19:56:48

标签: perl

如果我想获得与内置print类似的参数传递,如何声明函数原型,就像接受可选的第一个参数,即文件句柄?例如,调用语法为myprint $filehandle @mylist

2 个答案:

答案 0 :(得分:3)

Perl subs。

无法复制print的语法
$ perl -le'print defined(prototype("CORE::print")) ? "Can" : "Can'\''t", " be replicated"'
Can't be replicated

具体来说,语法NAME EXPR LIST不能用于调用Perl子,因为语法用于间接方法调用。 NAME EXPR LIST已经意味着EXPR->NAME(LIST)

选项1

# myprint $fh, LIST
# myprint *FH, LIST
# myprint \*FH, LIST

sub myprint {
   my $fh = shift;
   ...
}

选项2

# myprint $fh, LIST
# myprint *FH, LIST
# myprint \*FH, LIST
# myprint FH, LIST

sub myprint(*@) {
   my $fh = shift;
   if (!ref($fh)) {
      $fh = caller().'::'.$fh if $fh !~ /^(?:ARGV|STD(?:IN|OUT|ERR))\z/;
      no strict qw( refs );
      $fh = \*$fh;
   }

   ...
}

另一方面,即使print实际上也不支持print EXPR LIST。它支持以下语法:

print LIST         # Short for: print { select() } LIST
print IDENT LIST   # Short for: print { \*IDENT  } LIST
print $VAR LIST    # Short for: print { $VAR     } LIST
print BLOCK LIST

您实际上可以支持print的最终形式(其他只是快捷方式):

# myprint { select } LIST
# myprint { $fh } LIST
# myprint { *FH } LIST
# myprint { \*FH } LIST

sub myprint(&@) {
   my $fh = shift->();
   ...
}

我喜欢这个解决方案,而不是前两个。

答案 1 :(得分:2)

<td class="playerName md align-left pre in post" style="display: table-cell;"><span ...</span> <a role="button" class="full-name">Dustin Johnson</a> <a role="button" class="short-name">D. Johnson</a></td> 作为间接方法调用的示例,等同于

url = 'http://www.espn.com/golf/leaderboard?tournamentId=3742'

req = requests.get(url)
soup = bs4.BeautifulSoup(req.text,'lxml')

table = soup.find(id='leaderboard-view')
headings = [th.get_text() for th in table.find('tr').find_all('th')]

dataset = []

for row in table.find_all('tr'):
    a = [td.get_text() for td in row.find_all('td')]
    dataset.append(a)

要使用可以使用文件句柄间接调用的其他函数,请在print $fh @list包中定义它。

$fh->print(@list)

这适用于Perl v5.16及更好,并且不适用于Perl v5.12及更早版本,原因我没有调查过(可能是因为它直到v5.14或v5.16)所有文件句柄都自动加入IO::Handle

这似乎适用于所有版本的Perl,至少恢复到v5.8。 sub IO::Handle::myprint { my ($self, @list) = @_; #$self->print(scalar localtime,": ",@list); print $self scalar localtime, ": ", @list; } open my $fh, '>', 'foo'; print $fh "hello\n"; # IO::Handle::print($fh, "hello\n") myprint $fh "world\n"; # IO::Handle::myprint($fh, "world\n") close $fh; 方法中的语法IO::File需要v5.16(或者v5.14,只要所有文件句柄都被自动祝福$self->print(...)) - {{1}仍然适用于较旧的Perls。