カテゴリー別アーカイブ: perl

YAPC Asia 2013 へ参加してきた(メモ)


YAPC Asia 2013に参加してきました。初めて大型のカンファレンスへ参加しました。
単純にすごい刺激を受けました。

カンファレンス中に1つのモジュールをCPANにリリースする @tokuhirom さんとかすごすぎと思いました。
でも、とはいえやっぱりエンジニアとしてやっている以上、何か作って残していこうと思いました!!

それから数日後、初めてPull Requestが取り込まれたりして今後の1年間は積極的にオープンソースと関わったり、自分のプロダクトを出していこうと思います!!

ホント刺激になった。。。

ここからはあYAPCの時に気になったことのメモ

いまどきのカジュアルなデータベース開発

知らなかったMysql型 : utf8mb4

モダンPerlリファクタリング

  • CUIのプログラム
    モジュールをテストしやすい形に直す。
    テストから利用しやすいインターフェースにする。
    end2endのテスト(Test::Base)

  • Webアプリ
    Plack化する
    Plak::App::WrapCGIでPlack化する
    Plack化もできない場合はやはりEnd2Endのテストをする( Capybara )

  • 繰り返す
    より粒度の細かいテストを追加して、リファクタリングを進める

  • バグ
    バグを見つけたらバグを再現するテストを書く(回帰テスト)

  • 継続的に
    Travis-ci
    Guard + guard-tap
    テストは ほどほど にやる

  • リファクタリング
    リファクタリングの最初の一歩のEnd2Endのテストを書く。
    回帰テストで細かく進めていく

perl な web application のためのテスト情報

File::Temp
ファイルのアップロードなどのてすとで並列実行させたい時にアップロードするファイル名を変更する
tempfs

Programming AWS with Perl

AWS Command Line Interface とかの話

スライド:http://sssslide.com/http://www.slideshare.net/horiyasu/programming-aws-with-perl-at

AWS_CLIの使いかた
インストール方法
% pip install awscli

~/.aws/config にACCESS_KEY などを設定する

What’s new in Carton & cpanm

スライド:https://speakerdeck.com/miyagawa/whats-new-in-carton-and-cpanm-at-yapc-asia-2013

アンインストール
% cpanm uninstall Hoge

本当にあったレガシーな話

  • ログを取る
    • コメントアウトしているwarn()とか意味ない
    • スイッチ一発でログ出力したい
    • 基本はLog::Minimul
    • 本番環境にログを制御するコードを
    • 定数フラグでログ出力を制御する(if文で丁寧に細かくログ出力するコードを入れていく)
    • ログを丁寧に仕込むことで
  • mod_perlのApache::RequestをPlack::Requiestにする
  • Server::Starter
    –spawn-interval オプションでワーカープロセスの再起動を間隔空ける
    Server::Starter、Starman、Starletを使ったオレオレ運用方法
watchコマンドでプロセスの起動状況が見られる
% watch  -n 1 "ps -ef "
  • Rubyのkage

リンク集

Kansai.pm 第15回ミーティング 参加しましたー


Kansai.pm 第15回ミーティング
* 2013/2/23 14:00 -Yahoo大阪(大阪富国生命ビル27F)

ビルはとても綺麗だった。部屋も広くてとても快適に過ごせましたー!!参加した際の備忘録としてのメモ書き程度に。。。

『Webサービスのつくり方』のつくり方[@yusukebeさん]

オモロキでの仕事を7割。ボケて の開発。オモロキで爆速開発
Webサービスの作り方 著者

  • 2010年から2012年の間に執筆
  • MarkDown + Byword で執筆
  • DropBoxでファイルを共有
  • 自作アプリ「Dropdown」
    • マークダウンっぽい拡張子のファイルを Text::Markdown でWebページでプレビュー
    • WebService::DropBox を使ってDropbox内のファイルをプレビュー
  • Webサービスの作り方で書けなかった内容
  • Mojolicious推し
  • MVCモデルについて
  • Model重要・・・使いまわせる

BokeのWebアプリは以下の様なレイヤ構成になっている(上から順に高レイヤ)

  1. Bokete::Web::Controller::Boke
  2. Bokete::Model::Boke
  3. Bokete::DBx
  4. SQL::Abstract::Limit +DBI
  5. MySQL

Validationも工夫
* Form::FormValidator::Lite
* data on Model -> Data::Validator

  • AWS
    自動化、冗長化を助けてもらう
  • Cinnamon かわいい
    naoyaさんのレシピほぼまんま使っている

【感想】
WebService::DropBox(使ってみたい)
Cinnamonの評判が色んな所でいいとあるよな


MovableTypeについて[@junnamaさん]

WordPressのテンプレートとCakePHPのViewを 書ける

【感想】
MTの話ちょうど気になっていたので参考になった!!


コピペ検出器について(仮)[@goccy54さん]

動くコードを書く上でコピペが必要になるケースはある。(りふぁくたりんぐはしないとね)

PerlやJavaScriptいはコピペ検出器がない 何故無いのか??

作ってみた 

https://github.com/goccy/p5-Compiler-Tools-CopyPasteDetector

日本語での使い方


デプロイツールの作り方[@shiba_yu36さん]

Cinnamon について

有名なデプロイツール

  • Cappistrano
  • Archar

Cinnamonとは

  • perl製デプロイツール
  • perlでDSLっぽく設定を書ける

コンセプト

  • Minimum
  • Role(環境(productionなど)) + Task(実行するコマンドの単位)

Cinnamon側では サーバへのコマンド実行のみを提供。デプロイの方法は利用者に任せる

開発Tips

Net::OpenSSH 外部サーバにSSHでコマンドを実行してくれる
DSL 単なる関数 export Exporter::Lite 
Plack::Bulderを参考


全体を通しての感想

手を動かして作っていくことがいいなーと思った。なんでも手を動かして作ってみたい。ホントkansai.pmにでてやる気が出た。出張帰りと寝不足で懇親会に参加席なかったことが残念だったーー

【メモ】  

  • Milter(MailFilter)

[perl] MOP(メタオブジェクトプロトコル)について調べてみた


プログラミングのレベルを1つステップアップするためにメタプログラミングについて調査してみた。 メタプログラミングについては以下の書籍が有名だと思います。。この本はRubyをベースに書かれています。 実は読んだことがないのですが、次に読もう!!

MOP周りの用語

この記事の内容に書かれていることを抜粋
MooseとClass::MOPでメタプログラミング始めた

  • メタプログラミング
    ロジックを直接コーディングするのではなく、あるパターンをもったロジックを生成する高位ロジックによってプログラミングを行う方法

  • MOP(メタオブジェクトプロトコル)
    メタクラスを通してオブジェクトシステムへアクセスするAPI

  • メタクラス
    クラスの振る舞いを定義したクラスでイントロスペクション(introspection)とインターセッション(itercession)を備える

  • イントロスペクション
    オブジェクトの属性を得る能力 ex) 何のクラスを継承しているかとか、何のメソッドを持ってるかとか

  • インターセッション
    オブジェクトの振る舞いに変更を加える能力 ex) 親クラスを変更するとか、メソッドを追加するとか

メタプログラミングについて

メタプログラミングとはよく「プログラムをプログラムすること」と言われますが、どういうことでしょう?!
まつもとさんの書かれた記事にほぼ書いているのですが、
まつもと直伝 プログラミングのオキテ 第6回メタプログラミング

Perl の Mooseで説明すると、次のコードで説明できる。

■ MooseでHogeモジュール定義、mainで利用する

package Hoge;
use Moose;

has 'message' => (
    is => 'rw',
    required => 1,
);

# Hogeを利用するためのmainモジュール
package main;

my $obj = Hoge->new(message => "HOGE MESSAGE");
print $obj->message;   # HOGE MESSAGE

Hoge を new して message という属性(アトリビュート)のアクアクセサメソッドをつかって属性(アトリビュート)を設定したり、呼び出したりしている。ここでいう「has」メソッドが メタプログラミングされたメソッド となる。Mooseを定義することで自動で「new」メソッドができ、hasメソッドを書くことで message のセッター、ゲッターが暗黙的に利用できる状態になる。
このことをメタプログラミングと言って、「has」メソッドなど、 動的にオブジェクトやクラスにメソッドや属性を追加するための API を MOP という。そのMOPを提供するためのクラスをメタクラスという。
Perlでは Class::MOP が提供する。

Class::MOPを利用してみる

先ほどのHogeクラスをベースClass::MOPを使って動的にメソッドや属性を差し込む処理は以下の様な感じになります。

use strict;
use warnings;

package Hoge;
use Moose;

has 'message' => (
    is => 'rw',
    required => 1,
);

# このMooseのHogeクラスをClass::MOPのみでも作成することができる
# my $person_meta = Class::MOP::Class->create('Person');
#
# $person_meta->add_attribute(
#     'name',
#     accessor => 'name',
# );

##### ここから差し込むための処理 #####

package main;
use Class::MOP;

my $meta = Hoge->meta;  # [1] Hogeのメタクラスを取得

$meta->add_attribute(   # [2] nameという属性とアクセサメソッドの追加
    'name',
    accessor => 'name',
);

$meta->add_method(describe => sub { # [3] describeメソッドの追加
    my $self = shift;
    return "Name: ".$self->name.",  Message: ".$self->message;
});

my $hoge = Hoge->new(message => "I like soccer.", name => "YUSABANA");
  # オブジェクトの生成は以下のように$metaを使っても生成できる
  # $meta->new_object(message => "I like soccer.", name => "YUSABANA");

# 差し込んだメソッドdescribeを実行する
print $hoge->describe."\n";  # [4] Name: YUSABANA,  Message: I like soccer.

  • コード上[1]でHogeモジュールのメタクラスを取得する。
    このメタクラスを操作することで色々出来る。
  • コード上[2]は属性とアクセサメソッドを追加している。
  • コード上[3]はメソッドを追加している。
  • コード上[4]は追加したメソッドを実行して、画面出力する。

MOPを使えばこのように動的に処理を差し込むことができる。
Mooseの hasメソッドを定義している所でも add_attribute とかを使っているんだろ-なと予想できますねー!まだ、実際にコードは見ていないので確実ではないのですが。。。

  1. Class::MOP::Class – クラスに対するプロトコル
  2. Class::MOP::Attribute – アトリビュートに対するプロトコル
  3. Class::MOP::Method – メソッドに対するプロトコル
  4. Class::MOP::Instance – クラスのインスタンス生成に対するプロトコル

Moose::Util::TypeConstraints を使うと更に便利そう
http://idocsq.net/page/370

余談(Groovyでのメタプログラミング例)

■Stringクラスにhogeというメソッドを追加している。

String.metaClass.hoge = {->
    delegate.equals("hoge") ? true : false
}

println "hog".hoge()  //=> false
println "hoge".hoge() //=> true

[perl] 特殊変数 @INC %INC について (その他特殊変数について)


Perlはなんか特殊な変数が多くて大変です。。。とくにINC変数は特に重要というかCPANモジュールなどを入れるときや自分で定義したモジュールを読み込むなどで意識することがとても多くなるので、ちょっとまとめてみたいと思います。

@INC %INC の 説明

  • @INC … モジュールの検索パス(JavaでいうClassPathと同じ)
  • %INC … 読み込まれているモジュールの情報。ハッシュ形式でモジュールまでの絶対パスが格納される。

内容を確認する

次のようなコードで@INC, %INCをデバッグ出力してみる。
test.pl ( perl test.pl とコマンドを実行 )

use strict;
use warnings;
use DDP;

p @INC;
p %INC;

実行結果は以下のようになる。

■「p @INC;」の部分の実行結果。配列形式でモジュールの検索パスが格納されている。

[
    [0] "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2/darwin-2level",
    [1] "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2",
    [2] "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/darwin-2level",
    [3] "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2",
    [4] "."
]

■「p %INC;」の部分の実行結果。以下のようなハッシュ。
* key => パッケージが「package Hoge::Fuga」のようなFuga.pmモジュールの場合、
Hoge/Fuga.pmというキーとなる。
* value => 上記キーのファイルの絶対パスがバリューとなる。

{
    base.pm                                        "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/base.pm",
    B.pm                                           "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/darwin-2level/B.pm",
    bytes.pm                                       "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/bytes.pm",
    Carp/Heavy.pm                                  "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/Carp/Heavy.pm",
    Carp.pm                                        "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/Carp.pm",
    Class/Load.pm                                  "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2/Class/Load.pm",
    Class/Load/XS.pm                               "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2/darwin-2level/Class/Load/XS.pm",
    Class/MOP.pm                                   "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2/darwin-2level/Class/MOP.pm",
    Class/MOP/Attribute.pm                         "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2/darwin-2level/Class/MOP/Attribute.pm",
    Class/MOP/Class.pm                             "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2/darwin-2level/Class/MOP/Class.pm",
    Class/MOP/Class/Immutable/Trait.pm             "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2/darwin-2level/Class/MOP/Class/Immutable/Trait.pm",
・・・
・・・
省略
    unicore/Heavy.pl                               "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/unicore/Heavy.pl",
    unicore/lib/Perl/_PerlIDS.pl                   "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/unicore/lib/Perl/_PerlIDS.pl",
    utf8_heavy.pl                                  "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/utf8_heavy.pl",
    utf8.pm                                        "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/utf8.pm",
    vars.pm                                        "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/vars.pm",
    version.pm                                     "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/version.pm",
    warnings.pm                                    "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/warnings.pm",
    warnings/register.pm                           "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/warnings/register.pm",
    XSLoader.pm                                    "$HOME/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/XSLoader.pm"
}

余談

perlコマンドでperlスクリプトを実行する場合。実行時に@INCを追加することが出来る。

% perl -I[@INCに追加したいパス] test.pl


その他の特殊変数

特殊変数 意味
$. 読み込んでいるファイルの行番号
$$ プロセスID
$> 実行ユーザID
$] 実行グループID
$0 実行しているプログラム名
$^O OS名
$^T プログラムが起動した時刻
%ENV 環境変数($ENV{“Path”} という形で環境変数のPathを抽出する)
%SIG シグナルハンドラ
@ARGV コマンドライン引数
@_ サブルーチンの引数
$! OSのエラー
$@ 最後に実行した eval のエラー
@INC モジュールの検索パス
%INC 読み込まれているモジュールの絶対パスの情報

参考書籍

[perl]配列を一意にするuniq関数、ネストされた配列をフラットにする関数を書いた


経緯

タイトルに上げている関数を自分なりに書いてみたので、載せてみようと思います。
というのもこういうアルゴリズムの課題って、日々意識して置かないと、いざ書いてみようと思うとなかなか書くことが出来ないですよねー。。普段はプログラミング言語に用意されていたら、それ用のモジュールがあったりするので、アルゴリズムを意識しなくても同様の動作する関数はどこかしらから拾ってこれるので。。。

そういうゆるゆるにならないためにも、ちょっとずつでもこういう簡単なアルゴリズムは身につけられるように、、言語の勉強も兼ねて書いていこうと思いましたー!!


概要

以下の2つを実装してみました。

  1. 配列を一意にするuniq関数
    重複のある配列から重複を取り除いた形式の配列にする。
    ( 1, 3, 4, 7, 4, 8, 1, 3 ) => ( 1, 3, 4, 7, 8 )
  2. ネストされた配列をフラットにする関数
    配列の中に配列というように、ネスト構造にある配列を一つの配列にすべての要素を含むようにする。
    perlはネスト配列は配列リファレンスでしか扱えないと思うので、以下のようにしました。
    [1, 3, [3, 0], 4] => [1, 3, 3, 0, 4]

実装

Test::Moreを使って書きました。subtestsでテストを構造化して、上記2つのパターンをテストしています。
uniq_**という関数がuniq関数で、 flatten関数がネスト配列をフラットにする処理です。