(年末に向けて)久しぶりにPerlを書くぜ!ってなった時の Perl install メモ的な物です。
対象読者 or 前提条件 or 環境
- macな人
- ちょー久しぶりにPerlを書こうと思って
- Perlの最新版をいい感じにインストールする方法って何?
必要なもの
- Homebrew
- plenv : Perl版のrbenv的なもの
- perl : 最新の安定版は perl 5.30.1 (2019-11-23)
インストール
Homebrew で plenv, perl-build をインストール
$ brew install plenv
$ brew search perl
==> Formulae
perl perl-build perl6 perl@5.18 perltidy superlu
$ brew install perl-build
echo 'eval "$(plenv init -)"' >> ~/.bash_profile
$ plenv -v
plenv 2.2.0
plenv で Perl5.30.1をインストール
おそらく何もしていなければ、macに最初から入っているPerlを使っているはず。
$ perl -e 'print $^V'
v5.18.2
$ plenv help
$ plenv commands
$ plenv root
$ plenv install --help
$ plenv install -l | more
$ plenv install 5.30.1
$ plenv versions
* system (set by /Users/kazoo/.plenv/version)
5.30.1
$ plenv global 5.30.1
$ plenv versions
system
* 5.30.1 (set by /Users/kazoo/.plenv/version)
$ which perl
/Users/kazoo/.plenv/shims/perl
$ perl -e 'print $^V'
v5.30.1
CPANモジュールインストール
cpanmでインストールした後に、インストールしたモジュールが not found な時
注意点です。
plenvやcpanmを使ってPerlやモジュールを新たにインストールした時は、
plenv rehash
しましょう。
コマンドとか not found と言われますので。
LWP::UserAgent
$ plenv list-modules
Crypt::RC4
Digest::Perl::MD5
ExtUtils::MakeMaker
OLE::Storage_Lite
Perl
Spreadsheet::ParseExcel
Spreadsheet::WriteExcel
local::lib
$ plenv install-cpanm
$ cpanm LWP::UserAgent
$ plenv list-modules
App::cpanminus
Crypt::RC4
Date::Parse
Digest::Perl::MD5
Encode::Locale
ExtUtils::Config
ExtUtils::Helpers
ExtUtils::InstallPaths
ExtUtils::MakeMaker
File::Listing
HTML::Parser
HTML::Tagset
HTTP::Cookies
HTTP::Daemon
HTTP::Date
HTTP::Message
HTTP::Negotiate
IO::HTML
LWP::MediaTypes
Module::Build::Tiny
Net::HTTP
OLE::Storage_Lite
Perl
Spreadsheet::ParseExcel
Spreadsheet::WriteExcel
Test::Fatal
Test::Needs
Test::RequiresInternet
Try::Tiny
URI
WWW::RobotRules
libwww::perl
local::lib
LWP::Protocol::https
cpanm LWP::Protocol::https
--> Working on LWP::Protocol::https
Fetching http://www.cpan.org/authors/id/O/OA/OALDERS/LWP-Protocol-https-6.07.tar.gz ... OK
Configuring LWP-Protocol-https-6.07 ... OK
==> Found dependencies: Mozilla::CA, IO::Socket::SSL
--> Working on Mozilla::CA
Fetching http://www.cpan.org/authors/id/A/AB/ABH/Mozilla-CA-20180117.tar.gz ... OK
Configuring Mozilla-CA-20180117 ... OK
Building and testing Mozilla-CA-20180117 ... OK
Successfully installed Mozilla-CA-20180117
--> Working on IO::Socket::SSL
Fetching http://www.cpan.org/authors/id/S/SU/SULLR/IO-Socket-SSL-2.066.tar.gz ... OK
==> Found dependencies: Net::SSLeay
--> Working on Net::SSLeay
Fetching http://www.cpan.org/authors/id/C/CH/CHRISN/Net-SSLeay-1.88.tar.gz ... OK
Configuring Net-SSLeay-1.88 ... OK
Building and testing Net-SSLeay-1.88 ... OK
Successfully installed Net-SSLeay-1.88
Configuring IO-Socket-SSL-2.066 ... OK
Building and testing IO-Socket-SSL-2.066 ... OK
Successfully installed IO-Socket-SSL-2.066
Building and testing LWP-Protocol-https-6.07 ... OK
Successfully installed LWP-Protocol-https-6.07
4 distributions installed
JSON
$ cpanm JSON
--> Working on JSON
Fetching http://www.cpan.org/authors/id/I/IS/ISHIGAKI/JSON-4.02.tar.gz ... OK
Configuring JSON-4.02 ... OK
Building and testing JSON-4.02 ... OK
Successfully installed JSON-4.02
1 distribution installed
Dotenv
$ cpanm Dotenv
--> Working on Dotenv
Fetching http://www.cpan.org/authors/id/B/BO/BOOK/Dotenv-0.002.tar.gz ... OK
Configuring Dotenv-0.002 ... OK
==> Found dependencies: Path::Tiny, Test::Pod::Coverage, Test::CPAN::Meta, Test::Pod
--> Working on Path::Tiny
Fetching http://www.cpan.org/authors/id/D/DA/DAGOLDEN/Path-Tiny-0.108.tar.gz ... OK
Configuring Path-Tiny-0.108 ... OK
Building and testing Path-Tiny-0.108 ... OK
Successfully installed Path-Tiny-0.108
--> Working on Test::Pod::Coverage
Fetching http://www.cpan.org/authors/id/N/NE/NEILB/Test-Pod-Coverage-1.10.tar.gz ... OK
Configuring Test-Pod-Coverage-1.10 ... OK
==> Found dependencies: Pod::Coverage
--> Working on Pod::Coverage
Fetching http://www.cpan.org/authors/id/R/RC/RCLAMP/Pod-Coverage-0.23.tar.gz ... OK
Configuring Pod-Coverage-0.23 ... OK
==> Found dependencies: Devel::Symdump
--> Working on Devel::Symdump
Fetching http://www.cpan.org/authors/id/A/AN/ANDK/Devel-Symdump-2.18.tar.gz ... OK
Configuring Devel-Symdump-2.18 ... OK
Building and testing Devel-Symdump-2.18 ... OK
Successfully installed Devel-Symdump-2.18
Building and testing Pod-Coverage-0.23 ... OK
Successfully installed Pod-Coverage-0.23
Building and testing Test-Pod-Coverage-1.10 ... OK
Successfully installed Test-Pod-Coverage-1.10
--> Working on Test::CPAN::Meta
Fetching http://www.cpan.org/authors/id/B/BA/BARBIE/Test-CPAN-Meta-0.25.tar.gz ... OK
Configuring Test-CPAN-Meta-0.25 ... OK
Building and testing Test-CPAN-Meta-0.25 ... OK
Successfully installed Test-CPAN-Meta-0.25
--> Working on Test::Pod
Fetching http://www.cpan.org/authors/id/E/ET/ETHER/Test-Pod-1.52.tar.gz ... OK
Configuring Test-Pod-1.52 ... OK
Building and testing Test-Pod-1.52 ... OK
Successfully installed Test-Pod-1.52
Building and testing Dotenv-0.002 ... OK
Successfully installed Dotenv-0.002
7 distributions installed
Dotenv チートシート
.env
SUBDOMAIN='subdomain'
use Dotenv -load;
ENV{'SUBDOMAIN'} # 'subdomain'
jq
$ brew install jq
kintone REST API
record.json GET
3.pl
use strict;
use LWP::UserAgent;
use JSON;
use utf8;
use Encode;
use Data::Dumper; # debug
use Dotenv -load;
use MIME::Base64;
# ssl_opts https://metacpan.org/pod/LWP::UserAgent#ssl_opts
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
my $url = "https://${ENV{'SUBDOMAIN'}}.cybozu.com/k/v1/record.json";
my $req = HTTP::Request->new(GET => $url);
$req->header("Host" => "${ENV{'SUBDOMAIN'}}.cybozu.com:443");
$req->header("X-Cybozu-Authorization" => encode_base64("${ENV{'UID'}}:${ENV{'PASS'}}", ''));
$req->header("Content-Type" => "application/json");
$req->content('{"app":1,"id":1}');
my $res = $ua->request($req);
my $content = $res->content;
if ($res->is_success) {
my $json = JSON->new->utf8->decode($content);
print $json->{'record'}->{'$id'}->{'value'}, "\n";
print $json->{'record'}->{'レコード番号'}->{'value'}, "\n";
print encode('UTF-8' ,$json->{'record'}->{'文字列__1行_'}->{'value'}), "\n";
}else{
print $res->status_line, "\n";
}
メモ:
外からの入力に対しては基本decodeして、Perl内部文字列に変換する。
decode($content)
record.json POST
record-post.pl
use strict;
use LWP::UserAgent;
use JSON;
use utf8;
use Encode;
use Data::Dumper; # debug
use Dotenv -load;
use MIME::Base64;
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
my $url = "https://${ENV{'SUBDOMAIN'}}.cybozu.com/k/v1/record.json";
my $req = HTTP::Request->new(POST => $url);
$req->header("Host" => "${ENV{'SUBDOMAIN'}}.cybozu.com:443");
$req->header("X-Cybozu-Authorization" => encode_base64("${ENV{'UID'}}:${ENV{'PASS'}}", ''));
$req->header("Content-Type" => "application/json");
my $body = <<'EOS';
{
"app":1,
"record": {
"文字列__1行_": {
"value": "テスト株式会社3"
},
"ラジオボタン": {
"value": "C"
}
}
}
EOS
$req->content(encode('UTF-8', $body));
my $res = $ua->request($req);
my $content = $res->content;
if ($res->is_success) {
print 'success:', $res->status_line, "\n";
print $res->content, "\n";
my $json = JSON->new->utf8->decode($content);
print 'recordId:', $json->{'id'}, "\n";
print 'revision:', $json->{'revision'}, "\n";
}else{
print 'error:', $res->status_line, "\n";
print $res->content, "\n";
}
メモ:
外部に渡す場合はencodeする。encode('UTF-8', $body)
record.json GET with Basic Auth
record-get-basic-auth.pl
use strict;
use LWP::UserAgent;
use JSON;
use utf8;
use Encode;
use Data::Dumper; # debug
use Dotenv -load;
use MIME::Base64;
use base 'HTTP::Message';
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
my $url = "https://${ENV{'SUBDOMAIN2'}}.cybozu.com/k/v1/record.json";
my $req = HTTP::Request->new(GET => $url);
$req->header("Host" => "${ENV{'SUBDOMAIN2'}}.cybozu.com:443");
$req->header("X-Cybozu-Authorization" => encode_base64("${ENV{'UID2'}}:${ENV{'PASS2'}}", ''));
$req->header("Authorization" => 'Basic ' . encode_base64("${ENV{'BASICAUTHID'}}:${ENV{'BASICAUTHPASS'}}", ''));
$req->header("Content-Type" => "application/json");
$req->content('{"app":2,"id":1}');
# print Dumper $req;
my $res = $ua->request($req);
my $content = $res->content;
if ($res->is_success) {
print $res->is_success, "\n";
print $res->status_line, "\n";
# print $res->code, "\n";
print $content, "\n";
# print Dumper $res->content;
my $json = JSON->new->utf8->decode($content);
print $json->{'record'}->{'$id'}->{'value'}, "\n";
print $json->{'record'}->{'レコード番号'}->{'value'}, "\n";
print encode('UTF-8' ,$json->{'record'}->{'attend'}->{'value'}), "\n";
}else{
print $res->status_line, "\n";
}
jqを使ってJSONを整形
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
my $url = "https://${ENV{'SUBDOMAIN'}}.cybozu.com/k/v1/record.json";
my $req = HTTP::Request->new(GET => $url);
$req->header("Host" => "${ENV{'SUBDOMAIN'}}.cybozu.com:443");
$req->header("X-Cybozu-Authorization" => encode_base64("${ENV{'UID'}}:${ENV{'PASS'}}", ''));
$req->header("Content-Type" => "application/json");
$req->content('{"app":1,"id":1}');
my $res = $ua->request($req);
my $content = $res->content;
if ($res->is_success) {
my $json = JSON->new->utf8->decode($content);
open(CMD, "| jq '.'");
print CMD $content;
close(CMD);
}else{
print $res->status_line, "\n";
}
出力
{
"record": {
"レコード番号": {
"type": "RECORD_NUMBER",
"value": "1"
},
"Table": {
"type": "SUBTABLE",
"value": [
{
"id": "2",
(略)
"$revision": {
"type": "__REVISION__",
"value": "3"
},
"更新日時": {
"type": "UPDATED_TIME",
"value": "2017-06-25T11:41:00Z"
},
"作成日時": {
"type": "CREATED_TIME",
"value": "2017-06-24T09:04:00Z"
},
"$id": {
"type": "__ID__",
"value": "1"
}
}
}
参考
- plenv
- plenvを使ったPerl環境構築 〜2018年度版〜
- Perl
- https://perldoc.jp/
- 他言語ユーザから見たPerlのおもしろさ / YAPC::Nagoya::Tiny 2019
- https://tutorial.perlzemi.com/
- plenvの基本メモ書き
- cpanとperldocの歩き方
- JSON - JSONデータを解析
ライブラリ
ツールなど
モジュール
読み物的な
(技術的よりもどちらかというと読み物的な記事。結構大事)
テスト
所謂、Unit Test
Perl Mongers(Perlユーザーコミュニティ)
ToDo
2019-11-24
- cpanで良さげなライブラリを探して、REST API のラッパーを作る。