2011年12月14日星期三

[PerlChina] 2011 CN Perl Advent Day 14: CSV & XLS

http://perlchina.github.com/advent.perlchina.org/2011/CSV_XLS.html 

=for advent_year 2011

=for advent_day 14

=for advent_title CSV & XLS

=for advent_author Fayland Lam

Well, 很多人都喜欢用 Excel or OpenOffice Calc 来打开表格文件。所以您的上司,客户或者朋友,会让你输出 csv 或者 xls 给他们。

有些人喜欢直接用 print join(', ', map { '"' . $_ . '"' } @outs) 来输出成 CSV, 但是这是极度不好的行为,因为 outs 里可能有 " 也可能有 ,

所以个人建议,不管是解析 CSV 或者构造 CSV, 都应该使用标准的 CPAN 模块。如 M<Text::CSV_XS>

=begin code

use Data::Dumper;
use Text::CSV_XS;
my $csv = Text::CSV_XS->new ({ binary => 1 }) or
    die "Cannot use CSV: " . Text::CSV_XS->error_diag();

# read
open(my $fh, "<:encoding(utf8)", "test.csv") or die "test.csv: $!";
while (my $row = $csv->getline($fh)) {
    print Dumper(\$row);
}
$csv->eof or $csv->error_diag();
close($fh);

# read from string
my $line = "myid,filename,size as 9mb";
unless ($csv->parse($line)) {
    die "Failed to parse $line: " . $csv->error_diag() . "\n";
}
my @field = $csv->fields;
print Dumper(\@field);

# print out to file
$csv->print($fh, ['myid', 'filename', 'size as 9mb']); print $fh "\n";
# print out to STDOUT
$csv->print(\*STDOUT, \@rows); print "\n";

=end code

如果有人非要找你要 xls 格式的话,你可以简单的用一下 A<http://cpansearch.perl.org/src/HMBRAND/Text-CSV_XS-0.85/examples/csv2xls|csv2xls> 来转成 xls 给他们。(如果连接失效,可 google "csv2xls cpan")

但是如果他们需要一些特殊的 xls 功能的话,比如一些颜色,大小格式,或者 function 之类的,那我们就得求助于 M<Excel::Writer::XLSX> 了。

该模块由 M<Spreadsheet::WriteExcel> 的作者写的,相对 Spreadsheet::WriteExcel 提供了更好的性能和支持。

模块的使用也是非常简单的。(模块的使用都应该是很简单的,所有复杂的模块都是不合格的模块。:)

我们复制了 SYNOPSIS 过来。

=begin code

use Excel::Writer::XLSX;

# Create a new Excel workbook
my $workbook = Excel::Writer::XLSX->new( 'perl.xlsx' );

# Add a worksheet
$worksheet = $workbook->add_worksheet();

#  Add and define a format
$format = $workbook->add_format();
$format->set_bold();
$format->set_color( 'red' );
$format->set_align( 'center' );

# Write a formatted and unformatted string, row and column notation.
$col = $row = 0;
$worksheet->write( $row, $col, 'Hi Excel!', $format );
$worksheet->write( 1, $col, 'Hi Excel!' );

# Write a number and a formula using A1 notation
$worksheet->write( 'A3', 1.2345 );
$worksheet->write( 'A4', '=SIN(PI()/4)' );

=end code

2个模块都有非常详细的 EXAMPLES 目录。如果还是不会的话,可以来 PerlChina Group 发帖求助。

谢谢。

--
Fayland Lam // http://www.fayland.org/

--
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

Re: [PerlChina] 有好的perl调试器或者方法吗

可以参考一下 Devel::NYTProf 模块: https://metacpan.org/module/Devel::NYTProf

2011/12/14 fugang chang <fire_pot@hotmail.com>
hi,all
 
google到ptkdb工具,正在安装测试,不知道效果咋样~~
大家有没有好的perl调试器或者方法推荐下。
主要是想看下每步执行的时间,确定下优化的问题。谢谢。

--
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

--
您收到此邮件是因为您订阅了 Google 网上论坛的"PerlChina Mongers 讨论组"论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

[PerlChina] 有好的perl调试器或者方法吗

hi,all
 
google到ptkdb工具,正在安装测试,不知道效果咋样~~
大家有没有好的perl调试器或者方法推荐下。
主要是想看下每步执行的时间,确定下优化的问题。谢谢。

[PerlChina] Getopt::Euclid

大家跑demo-euclid.pl慢吗?我这儿有时候还好有时候很慢,操作系统是Windows XP,Perl版本
C:\>perl -v

This is perl, v5.10.0 built for MSWin32-x86-multi-thread


在 2011年12月4日 下午6:48,joe jiang <lamp.purl@gmail.com>写道:
Hi I have made one for the 4th day:)

=for advent_year 2011

=for advent_day 4

=for advent_title Getopt::Euclid

=for advent_author Joe Jiang

写脚本的时候,最麻烦的两件事,无非是写文档和设计用户接口。有了 Getopt::Euclid,这两件事情居然开始变得十分有趣了。应该说,文档驱>动的程序,这样的创意并不少见,可是用来作为用户接口,这真的还是让人觉得十分恰当。

相比其他的脚本参数分析模块,这个模块的知名度比较低,不过它的作者 Damian Conway 还是十分知名的。现在的维护者 Florent Angly 看起来
也是参数模块这方面的爱好者,一同被他收纳的还有 Getopt::Declare。

具体的使用方法可以参考以下的测试代码:

=begin code

    #!/usr/bin/perl -wl

    use Getopt::Euclid;
    print for @{$ARGV{-i}};

    =head1 NAME

    demo-euclid - testing of module Getopt::Euclid

    =head1 VERSION

    This documentation refers to demo-euclid version 0.0.1

    =head1 USAGE

        demo-euclid [options]  -i[n][file] <file>

    =head1 REQUIRED ARGUMENTS

    =over

    =item  -i[n][file] <file>

    Specify input file

    =for Euclid:
        repeatable
        file.type:    readable
        file.default: '-'

    =back

=end code

有了以上的代码,你就可以这样测试一下了:

=begin code

    $ perl demo-euclid.pl --version
    This is demo-euclid.pl version 0.0.1

=end code

看上去还不错,这个工具脚本已经可以自动汇报版本号了!然后再测试一下正式的功能:

=begin code

    $ perl demo-euclid.pl -i /etc/passwd -i /etc/group
    /etc/passwd
    /etc/group

=end code

这正是我们的工具需要的功能,也就是分行(因为 #! 行的末尾有个 l 选项)打印文件名。另外,文件不存在,或者不可读的时候,脚本还会自>动报错:

=begin code


    $ perl demo-euclid.pl -i /etc/pass
    Invalid "-i[n][file] <file>" argument.
    <file> must be readable but the supplied value ("/etc/pass") isn't.
    (Try: demo-euclid.pl --help)

    $ perl demo-euclid.pl --help
    Usage:

    demo-euclid.pl -i <file>
    ...

=end code

看上去还挺专业的,连相应的帮助信息也有了。衷心希望你会喜欢上这个小模块!


--
您收到此邮件是因为您订阅了 Google 网上论坛的"PerlChina Mongers 讨论组"论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

2011年12月13日星期二

Re: [PerlChina] 2011 CN Perl Advent Day 13: Gmail

厉害厉害,gmail 都用上了


 
2011/12/13 Fayland Lam <fayland@gmail.com>
http://perlchina.github.com/advent.perlchina.org/2011/Gmail.html 

=for advent_year 2011

=for advent_day 13

=for advent_title Gmail

=for advent_author Fayland Lam

Gmail 挺不错的。本章主要介绍如何使用 IMAP 来收取邮件和如何在 TLS 上发送邮件。

Gmail 支持 POP3, 但是个人更喜欢用 IMAP,因为可以只查询未读邮件,和标记为已读,无须将其删除。还有它还能检查非 INBOX 的邮件。

IMAP 一般使用 M<Mail::IMAPClient>, 使用例子如下:

=begin code

use Mail::IMAPClient;
use IO::Socket::SSL;

# Connect to IMAP server
my $imap = Mail::IMAPClient->new(
  Server   => 'imap.gmail.com',
  User     => 'myusername@gmail.com', # or App mail
  Password => 'mysecretpass',
  Port     => 993,
  Ssl      =>  1,
) or die "Cannot connect through IMAPClient: $!";

$imap->select("INBOX");
$imap->Peek(1); # we'll use see to mark as read
my @unseen = $imap->unseen or print "No unseen messages in inbox\n";
foreach my $msg_id (@unseen) {
    my $msg_from = $imap->get_header($msg_id, "From");
    my $msg_subject = $imap->get_header($msg_id, "Subject");
    my $string = $imap->body_string($msg_id)
        or die "Could not body_string: ", $imap->LastError;
    print "We get $msg_subject from $msg_from: $string\n";
    
    $imap->see($msg_id); # mark as read if needed
}

# Say so long
$imap->logout();

=end code

邮件的用途比较广泛,比如你在其他地方或者某些人会经常给你发送一些特定格式的邮件,您可以写个脚本来处理这些。

另外我们也经常需要发送邮件,如果要大批量发送的话,sendmail, Qmail 或者 Postfix 等是一个不错的选择,但是如果仅仅是需要偶尔发送一些邮件,还是可以使用 Gmail 的 SMTP 服务器的。这里我们用 M<Email::Sender::Simple> 和 M<Email::Sender::Transport::SMTP::TLS> 来发送。

=begin pre

use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP::TLS;
use Try::Tiny;

my $transport = Email::Sender::Transport::SMTP::TLS->new(
    host => 'smtp.gmail.com',
    port => 587,
    username => 'myusername@gmail.com',
    password => 'mysecretpass',
);


use Email::Simple::Creator; # 需要发送附件的话,可以试试 MIME::Lite 到最后 my $message = $msg->as_string; 即可
my $message = Email::Simple->create(
    header => [
        From    => 'myusername@gmail.com',
        To      => 'mylove@mail.com',
        Subject => 'Hi Baby',
    ],
    body => 'I Love you!',
);

try {
    sendmail($message, { transport => $transport });
} catch {
    die "Error sending email: $_";
};

=end pre

更多更详细的资料,请参阅各自的 perldoc

谢谢。


--
Fayland Lam // http://www.fayland.org/

--
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。



--
            Yours Sincerely
                    Zeng Hong

--
您收到此邮件是因为您订阅了 Google 网上论坛的"PerlChina Mongers 讨论组"论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

[PerlChina] 2011 CN Perl Advent Day 13: Gmail

http://perlchina.github.com/advent.perlchina.org/2011/Gmail.html 

=for advent_year 2011

=for advent_day 13

=for advent_title Gmail

=for advent_author Fayland Lam

Gmail 挺不错的。本章主要介绍如何使用 IMAP 来收取邮件和如何在 TLS 上发送邮件。

Gmail 支持 POP3, 但是个人更喜欢用 IMAP,因为可以只查询未读邮件,和标记为已读,无须将其删除。还有它还能检查非 INBOX 的邮件。

IMAP 一般使用 M<Mail::IMAPClient>, 使用例子如下:

=begin code

use Mail::IMAPClient;
use IO::Socket::SSL;

# Connect to IMAP server
my $imap = Mail::IMAPClient->new(
  Server   => 'imap.gmail.com',
  User     => 'myusername@gmail.com', # or App mail
  Password => 'mysecretpass',
  Port     => 993,
  Ssl      =>  1,
) or die "Cannot connect through IMAPClient: $!";

$imap->select("INBOX");
$imap->Peek(1); # we'll use see to mark as read
my @unseen = $imap->unseen or print "No unseen messages in inbox\n";
foreach my $msg_id (@unseen) {
    my $msg_from = $imap->get_header($msg_id, "From");
    my $msg_subject = $imap->get_header($msg_id, "Subject");
    my $string = $imap->body_string($msg_id)
        or die "Could not body_string: ", $imap->LastError;
    print "We get $msg_subject from $msg_from: $string\n";
    
    $imap->see($msg_id); # mark as read if needed
}

# Say so long
$imap->logout();

=end code

邮件的用途比较广泛,比如你在其他地方或者某些人会经常给你发送一些特定格式的邮件,您可以写个脚本来处理这些。

另外我们也经常需要发送邮件,如果要大批量发送的话,sendmail, Qmail 或者 Postfix 等是一个不错的选择,但是如果仅仅是需要偶尔发送一些邮件,还是可以使用 Gmail 的 SMTP 服务器的。这里我们用 M<Email::Sender::Simple> 和 M<Email::Sender::Transport::SMTP::TLS> 来发送。

=begin pre

use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP::TLS;
use Try::Tiny;

my $transport = Email::Sender::Transport::SMTP::TLS->new(
    host => 'smtp.gmail.com',
    port => 587,
    username => 'myusername@gmail.com',
    password => 'mysecretpass',
);


use Email::Simple::Creator; # 需要发送附件的话,可以试试 MIME::Lite 到最后 my $message = $msg->as_string; 即可
my $message = Email::Simple->create(
    header => [
        From    => 'myusername@gmail.com',
        To      => 'mylove@mail.com',
        Subject => 'Hi Baby',
    ],
    body => 'I Love you!',
);

try {
    sendmail($message, { transport => $transport });
} catch {
    die "Error sending email: $_";
};

=end pre

更多更详细的资料,请参阅各自的 perldoc

谢谢。


--
Fayland Lam // http://www.fayland.org/

--
您收到此邮件是因为您订阅了 Google 网上论坛的“PerlChina Mongers 讨论组”论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。

2011年12月12日星期一

[PerlChina] AnyEvent timer + AnyEvent-HTTP 出现的memleak问题

Hi all,

貌似最近AnyEvent挺火,以前也尝试过,实在用不怪,
近几天又拿来用,发现个问题。

如下例,
AnyEvent timer 回调中设置了一个AnyEvent::HTTP的http_get,
并且指定一个代理,这段代码运行一个小时内存使用了100M,
若去掉代理,内存消耗就正常。

若改下代码,http_get放在一个循环中,则也未见memleak出现。

搞不清这个memleak 是由timer引起的,还是AnyEvent-HTTP引起的。
是bug? 还是我没用好?

帮忙分析下,先谢。

Code:
##################
use AnyEvent;
use AnyEvent::HTTP;

local $| = 1;

my $cv = AnyEvent->condvar;
my $url = 'http://www.google.com';

my $w1 = AnyEvent->timer(
after => 1,
interval => 1,
cb => sub { get($url) },
);

$cv->recv;

sub get {
my $url = shift;

AnyEvent::HTTP::http_get ($url, proxy => ['127.0.0.1', 8080], sub {
my ($body, $hdr) = @_;
print $hdr->{Status}, "\n";
});
}
####################

--
您收到此邮件是因为您订阅了 Google 网上论坛的"PerlChina Mongers 讨论组"论坛。
要向此网上论坛发帖,请发送电子邮件至 perlchina@googlegroups.com。
要取消订阅此网上论坛,请发送电子邮件至 perlchina+unsubscribe@googlegroups.com。
若有更多问题,请通过 http://groups.google.com/group/perlchina?hl=zh-CN 访问此网上论坛。