2010年1月18日月曜日
速度考えないとだけどIterator抽象化してみた
ちょっと変更。こんなかんじでいいのか?
ちゃんと速度とかメモリ消費とか考えないとだけどやってない。
#実行
use File;
use Array;
use Iterator;
my $iter = Iterator->new(array=>[2,4,6,8,10]);
my $len = $iter->size();
print "len:$len\n";
while($iter->hasNext()){
my $index = $iter->index();
my $data = $iter->next();
print "index:$index data:$data\n";
}
$iter = ();
my $iter2 = Iterator->new(file=>'001.txt');
while($iter2->hasNext()){
my $linecnt = $iter2->linecnt;
print "linecnt:$linecnt\n";
my $x = $iter2->next;
print "x:$x\n";
}
print "Finish\n";
my $iter3 = Iterator->new();
#Role
package RoleIter;
use Moose::Role;
requires qw(next hasNext);
no Moose::Role;
1;
#Iterator
package Iterator;
use Moose;
use RoleIter;
use File;
use Array;
has class =>(
is => 'rw',
does => 'RoleIter',
handles => [qw(next hasNext index linecnt size)],
);
__PACKAGE__->meta->make_immutable;
no Moose;
use File;
use Array;
sub BUILD{
my ($self,$args_ref) = @_;
if(exists $args_ref->{file}){
my $file = File->new($args_ref);
$self->class($file);
}elsif(exists $args_ref->{array}){
my $array = Array->new($args_ref);
$self->class($array);
}else{
die "!exists args";
}
}
sub DEMOLISH{print "Iterator->DEMOLISH\n"}
1;
#Array
package Array;
use Moose;
use MooseX::AttributeHelpers;
with 'RoleIter';
has array =>(
metaclass => 'Collection::Array',
is => 'rw',
isa => 'ArrayRef',
required => 1,
trigger => sub{
my ($self,$list) = @_;
$self->size(scalar @$list);
},
provides => {
get => 'array_get'
}
);
has size => ( is => 'rw', isa => 'Int', default => 0,);
has index =>(
metaclass => 'Number',
is => 'rw',
isa => 'Int',
default => 0,
provides => {
add => 'add_index'
}
);
__PACKAGE__->meta->make_immutable;
no Moose;
sub next{
my ($self) = @_;
my $i = $self->index;
$self->add_index(1);
return $self->array_get($i);
}
sub hasNext{
my ($self) = @_;
if($self->index >= $self->size){
return 0;
}else{
return 1;
}
}
1;
#File
package File;
use Moose;
use MooseX::Types::Path::Class;
use MooseX::AttributeHelpers;
with 'RoleIter';
has file => ( is=>'rw',isa=>'Path::Class::File',coerce=>1,required=>1,);
has fh => ( is=>'rw',isa=>'IO::File',lazy_build=>1,);
has linestr => (is=>'rw',isa=>'Str',default=>'');
has linecnt =>(
metaclass => 'Number',
is => 'rw',
isa => 'Int',
default => 0,
provides => {
add => 'add_linecnt'
}
);
__PACKAGE__->meta->make_immutable;
no Moose;
sub _build_fh{
my $self = shift;
return $self->file->openr();
}
sub hasNext{
my ($self) = @_;
# $fh: Grob
my $fh = $self->fh;
my $line = <$fh>;
if(defined $line){
$line =~ s/\s+$//;
$self->linestr($line);
$self->add_linecnt(1);
return 1;
}else{
return 0;
}
}
sub next{
my ($self) = @_;
return $self->linestr;
}
1;
2010年1月15日金曜日
2010年1月14日木曜日
Moose委譲に挑戦したらエラー
って、下に貼り付けてたらわかったよ。
does => 'TEST_Function', だ。
今回の場合はis=> 'TEST_Function', か。
すげーよMoose。っつーかオブジェクト指向か?デザインパターンか?
同じ機能を持って別の処理をするときはここにRoleを指定するのね。
それで実際にNewするときはRoleで要求するメソッドを持ったクラスを渡すと。
そうすると、処理は違う、機能は同じみたいなこと(数値のSortと文字列のSortとか)は それぞれやりたいことができるクラスを用意しておいて、場面に応じてクラスを変えると。すげー。
過去のプログラム全部書き直したくなってきた。
package testGUI;
use Moose;
has function =>(
is => 'rw',
does => 'TEST_Function',
handles => [qw(A B C)],
);
has ui =>(
is => 'rw',
does => 'TEST_UI',
handles => [qw(E F G)],
);
__PACKAGE__->meta->make_immutable;
no Moose;
1;
package TEST_Function;
use Moose;
__PACKAGE__->meta->make_immutable;
no Moose;
sub A{
print "TEST_Function->A\n";
}
sub B{
print "TEST_Function->B\n";
}
sub C{
print "TEST_Function->C\n";
}
1;
package TEST_UI;
use Moose;
__PACKAGE__->meta->make_immutable;
no Moose;
sub E{
print "TEST_UI->E\n";
}
sub F{
print "TEST_UI->F\n";
}
sub G{
print "TEST_UI->G\n";
}
1;
Mooseのシュガー関数
複雑な処理を書くことなく、全部Mooseにお任せして、うしろでやってもらう。hasとか。
エクスポートしてるので no Moose で除去。これで名前 関数名の衝突を防ぐ。
2010年1月13日水曜日
DBI SQL プレースホルダーは当たり前?
すごいね。
「プレースホルダーはSQL文内に実行時に置換されるべき値があることを指定し、SQL文として安全な形に整形されるようにする仕組みです。」
とある。
my $sql = 'select * from A where id = ?';
my $statementH = $dbh->prepare($sql);
$statementH->execute('ID1');
while(my @data = $statementH->fetchrow_array) {
print "@data";
}
$statementH->finish;
2010年1月12日火曜日
アジャイルとウォーターフォール
ウォーターフォールやRUPなどの“重厚な(ヘビーウェイト)開発プロセス”が事前に仕様を定義して、それに基づいてアーキテクチャ中心に計画的な設計を行い(この間、仕様書や設計書など中間成果物を作成する)、その設計に沿ってプログラミングを行っていくというプロセスであるのに対して、
アジャイルソフトウェア開発は仕様や設計の(場合によっては大幅な)変更が当然あるものという前提で、最初から厳密な仕様を抽出しようとせず、大まかな仕様だけで細かいイテレーション(反復)開発に始め、すぐに実装・テストを行って仕様や設計の妥当性を検証するというアプローチを取る。
2010年1月7日木曜日
よくやるファイル処理にIterator導入してみる(Perl)
hasNext(), next(), linecnt を入れてみる。
MyIterator を 実装する File2.pmを変えてみる
package MyIterator::File2;
use Moose;
use MooseX::Types::Path::Class;
use MooseX::AttributeHelpers;
with 'MyIterator';
has file => ( is=>'rw',isa=>'Path::Class::File',coerce=>1,required=>1,);
has fh => ( is=>'rw',isa=>'IO::File',lazy_build=>1,);
has linestr => (is=>'rw',isa=>'Str',default=>'');
has linecnt =>(
metaclass => 'Number',
is => 'rw',
isa => 'Int',
default => 0,
provides => {
add => 'add_linecnt'
}
);
__PACKAGE__->meta->make_immutable;
no Moose;
sub _build_fh{
my $self = shift;
return $self->file->openr();
}
sub hasNext{
my ($self) = @_;
# $fh: Grob
my $fh = $self->fh;
my $line = <$fh>;
#print "fh:$fh\n";
if(defined $line){
$line =~ s/\s+$//;
$self->linestr($line);
$self->add_linecnt(1);
return 1;
}else{
return 0;
}
}
sub next{
my ($self) = @_;
return $self->linestr;
}
1;
2010年1月6日水曜日
List Map Set
多数の値をまとめて操作する→配列
→Javaの配列 使い勝手 悪い 要素固定、同じ 種類の値のみ
→ 多数の値(オブジェクト)を柔軟に扱うことを考えて用意されたのが「コレクション・フレームワーク」
「List」「Map」「Set」の3つが、コレクションの基本
LIST
要素の順番が保障されている。
決まった順番に常にオブ ジェクトが取り出される
MAP
キーで管理
SET
ユニーク 重複なし
2010年1月5日火曜日
2.5Flyweight
Flyweightは、オブジェクトを多数作成するときに消費されるメモリ量を減らすために使うパターンです。Flyweightはオブジェクトの作成をFactoryにゆだねますが、その中で毎回インスタンスを作成するのではなく、すでに作成してあるオブジェクトを返すようにする仕組みです。
2.4Factoryパターン
Factoryパターンはオブジェクトの作成およびそれに必要な諸処理を使用者側にさせたくない場合に使用します。
これはあれだ。Factoryパターンという名前を知らなくても普通にやってることだ。
2010年1月1日金曜日
2.3 Compositeで一括処理
Compositeパターン:複数のオブジェクトにたいしての処理と単一オブジェクトにたいしての処理に差がない場合に使用。
例では円と四角形のすべてを0.5倍にした。
一回の操作で全ての図を変更した。