詩と創作・思索のひろば

ドキドキギュンギュンダイアリーです!!!

Fork me on GitHub

To install Math::BigInt::GMP with homebrewed GMP

The Problem

% cpanm -v Math::BigInt::GMP
cpanm (App::cpanminus) 1.7000 on perl 5.014002 built for darwin-2level
Work directory is /Users/motemen/.cpanm/work/1381980252.48465
You have make /usr/bin/make
You have LWP 6.05
You have /usr/bin/tar: bsdtar 2.8.3 - libarchive 2.8.3
You have /usr/bin/unzip
Searching Math::BigInt::GMP on cpanmetadb ...
--> Working on Math::BigInt::GMP
Fetching http://www.cpan.org/authors/id/P/PJ/PJACKLAM/Math-BigInt-GMP-1.37.tar.gz ... OK
Unpacking Math-BigInt-GMP-1.37.tar.gz
x Math-BigInt-GMP-1.37/
x Math-BigInt-GMP-1.37/BUGS
x Math-BigInt-GMP-1.37/build/
x Math-BigInt-GMP-1.37/build/leak.pl
x Math-BigInt-GMP-1.37/build/leaktest
x Math-BigInt-GMP-1.37/build/README
x Math-BigInt-GMP-1.37/CHANGES
x Math-BigInt-GMP-1.37/CREDITS
x Math-BigInt-GMP-1.37/GMP.xs
x Math-BigInt-GMP-1.37/inc/
x Math-BigInt-GMP-1.37/inc/Devel/
x Math-BigInt-GMP-1.37/inc/Devel/CheckLib.pm
x Math-BigInt-GMP-1.37/INSTALL
x Math-BigInt-GMP-1.37/lib/
x Math-BigInt-GMP-1.37/lib/Math/
x Math-BigInt-GMP-1.37/lib/Math/BigInt/
x Math-BigInt-GMP-1.37/lib/Math/BigInt/GMP.pm
x Math-BigInt-GMP-1.37/LICENSE
x Math-BigInt-GMP-1.37/Makefile.PL
x Math-BigInt-GMP-1.37/MANIFEST
x Math-BigInt-GMP-1.37/MANIFEST.SKIP
x Math-BigInt-GMP-1.37/META.json
x Math-BigInt-GMP-1.37/META.yml
x Math-BigInt-GMP-1.37/README
x Math-BigInt-GMP-1.37/SIGNATURE
x Math-BigInt-GMP-1.37/t/
x Math-BigInt-GMP-1.37/t/00sig.t
x Math-BigInt-GMP-1.37/t/01load.t
x Math-BigInt-GMP-1.37/t/02pod.t
x Math-BigInt-GMP-1.37/t/03podcov.t
x Math-BigInt-GMP-1.37/t/bigfltpm.inc
x Math-BigInt-GMP-1.37/t/bigfltpm.t
x Math-BigInt-GMP-1.37/t/bigintg.t
x Math-BigInt-GMP-1.37/t/bigintpm.inc
x Math-BigInt-GMP-1.37/t/bigintpm.t
x Math-BigInt-GMP-1.37/t/biglog.t
x Math-BigInt-GMP-1.37/t/bigroot.t
x Math-BigInt-GMP-1.37/t/storable.t
x Math-BigInt-GMP-1.37/t/threads.t
x Math-BigInt-GMP-1.37/TODO
x Math-BigInt-GMP-1.37/typemap
Entering Math-BigInt-GMP-1.37
Checking configure dependencies from META.json
Checking if you have ExtUtils::MakeMaker 0 ... Yes (6.68)
Running Makefile.PL
Configuring Math-BigInt-GMP-1.37 ... Can't link/include 'gmp'
N/A
! Configure failed for Math-BigInt-GMP-1.37. See /Users/motemen/.cpanm/work/1381980252.48465/build.log for details.

The Solution

% cpanm Math::BigInt::GMP --configure-args="LIBS=-L$(brew --prefix gmp)/lib\ -lgmp INC=-I$(brew --prefix gmp)/include"
--> Working on Math::BigInt::GMP
Fetching http://www.cpan.org/authors/id/P/PJ/PJACKLAM/Math-BigInt-GMP-1.37.tar.gz ... OK
Configuring Math-BigInt-GMP-1.37 ... OK
Building and testing Math-BigInt-GMP-1.37 ... OK
Successfully installed Math-BigInt-GMP-1.37
1 distribution installed

Success!!

Shipped AnyEvent::Plackup

https://metacpan.org/release/MOTEMEN/AnyEvent-Plackup-0.01

(Japanese entry at: http://subtech.g.hatena.ne.jp/motemen/20120920/1348138250)

Simple obvious usage

use AnyEvent::Plackup;

my $server = plackup(app => \&psgi_app, port => $port);
say $server; # stringifies to server origin, e.g. "http://0.0.0.0:$port"

You may omit port number and random open one is chosen.

In this example, this is only a wrapper of Twiggy. But what makes this module useful is that you can omit even the app parameter.

Non-app usage

my $server = plackup();

Invoking plackup without app specified, you can serve responses without a PSGI-coderef. To handle requests:

my $req = $server->recv;
$req->respond([ 200, [], [ 'OK' ] ]);

Calling $server->recv makes the program wait for a request coming (AnyEvent loop starts). The returned request object is a Plack::Request equipped with one extra method, respond. Giving a PSGI response (or a coderef) to this method, you can serve response to the client.

Highly useful, for example, if you are writing a simple script that requires OAuth and you want to establish an HTTP server just only to receive an auth token.

For an example, see eg/google-oauth.pl.

use strict;
use warnings;
use autodie ':all';
use Net::OAuth2::Profile::WebServer;
use JSON::XS qw(decode_json);
use Browser::Open qw(open_browser);
use AnyEvent::Plackup;

# Obtain one at Google Cloud Console <https://cloud.google.com/console>.
my $client_secret = do {
    open my $fh, '<', 'client_secret.json';
    local $/;
    decode_json scalar <$fh>;
};

my $server = plackup(port => 4000);
my $auth = Net::OAuth2::Profile::WebServer->new(
    client_id        => $client_secret->{web}->{client_id},
    client_secret    => $client_secret->{web}->{client_secret},
    authorize_url    => $client_secret->{web}->{auth_uri},
    access_token_url => $client_secret->{web}->{token_uri},
    scope            => 'openid profile',
    redirect_uri     => "http://localhost:$server->{port}/",
);

open_browser $auth->authorize;

my $req = $server->recv; # Program stops here until user comes to http://localhost:4000/
   $req->respond([ 200, [], [ 'Thank you! Now go back to the console.' ] ]);

my $access_token = $auth->get_access_token($req->parameters->{code});

my $res = $access_token->get('https://www.googleapis.com/oauth2/v1/userinfo');

my $user_info = decode_json $res->decoded_content;

print "Hello, $user_info->{name}.\n";

Once you send the user to the browser, then he/she is redirected to your temporary server, and you will get the auth. The user is not required to enter PIN by his/her hand.

Thank you very much to @tokuhirom and @schmorp, for giving me advice for this module!

パール、アナルを使え!または私は如何にして Perl のワンライナーを書けるようになったか

簡単に言うとこういうことです。今日はこれだけ覚えて帰ってください。

perl -anal -e "…"

同様のオプションは Ruby でも使えます。

解説

-a

いきなり見かけないオプションですが、入力を空白文字で区切り、@F という配列に入れてくれます。それ以外の影響はないので使わないときでも指定して問題なし。2 回指定してるのも意味ないです。語呂合わせです。Ruby の場合は $F ですね。

-n

-e で指定されたコードを

LINE:
while (<>) {
    …
}

で囲みます。標準入力やファイルを一行ずつ処理するときに便利。sedgrep が簡単に書けますね。ワンライナーでは多様するオプションでしょう。代わりに -p を指定することで最後に print; することもできます。

-l

-n-p が指定されているときに各入力を chomp します。また、各出力に改行を追加します。

というのが表面的な説明で、実際には $/$\ などの特殊な変数の値が書き変わっています。-0 と組み合わせると場合によっては便利です。

% perl -ln0 -e "…"

などとすると入力を "\0" で区切り、各出力の末尾に改行文字が追加されるようになります。

ちなみに

この辺の話は perldoc perlrun で読めます。

B::Deparse を使うと何が起こっているのか分かりやすいですね。

% perl -MO=Deparse -anal -e 'poyo()'
BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    our(@F) = split(' ', $_, 0);
    poyo();
}

おわりです

ひとりでできるもん ~オトコのコのためのアナニー入門~

ひとりでできるもん ~オトコのコのためのアナニー入門~

はてなで一緒に働きませんか?