2008-01-01から1年間の記事一覧

Lambda Expressions

Acme::Lambda::Expr わーいラムダが簡単に書けるよー\(^o^)/ *1 use feature 'say'; use Acme::Lambda::Expr qw(:all); my $f = abs($x - $y) ** 2; say $f->(10, 5); # => 25 $f = curry $f, 5, $x; say $f->(12); # abs(5 - 12) ** 2 = 49 まさにナン…

「Xのリファレンスかどうか」の判定

Xのリファレンスかどうかの判定はどう考えればいいんだろう。とりあえず配列リファレンスで考えてみる。 まず,基本的な考え方は以下の4つだと思う。 use Scalar::Util qw(reftype); ref($x) eq 'ARRAY'; # 1 reftype($x) eq 'ARRAY'; # 2 ref($x) eq 'ARRAY…

Class::MOPベースのオブジェクトではカプセル化を実現できない?

Class::MOPに基づくインスタンスMOPでは以下のようなメソッドを提供しなければならないんだけど… package Class::MOP::Instance; #... sub set_slot_value { my ($self, $instance, $slot_name, $value) = @_; $instance->{$slot_name} = $value; } #... こ…

曖昧なメソッド呼び出し

{ package Foo; sub foo{} } { package Bar; sub foo{} } { package Baz; use parent -norequire => qw(Foo Bar); } Baz->foo(); # Ambiguous! こんなときのBaz->foo()はメソッド解決順序(MRO)に依存している曖昧なメソッド呼び出しです。 C++だと,このよう…

use Data::Util -fast_isa; の詳細

(2008/11/16 追記: perl/5.10.1からUNIVERSAL::isa()が改善されることに伴い,Data::Util/0.20から-fast_isaオプションは削除されました)昨日の続き。UNIVERSAL::isaとData::Util::fast_isaで何が違うのかというと,核心部分のソースはこんな感じ。細部はと…

Data::Util (Scalar::Util::Refから改名+α)

Data::Util こんな汎用的な名前を付けてしまっていいのだろうかと思いつつリリース。sv_derived_from()はもっと高速に実装できるはず,というアイデアを取り込んでみました*1。 use Data::Utilするときに-fast_isaオプションをつけると,UNIVERSAL::isaを高…

Module::Setup (2)

Module::Setupの追記。 yappo もうちょっと詳しく教えてもらったら、なんかできるかもしれませんわざわざコメントありがとうございます。 module-setup Fooなどとしたときに,ディストリビューションディレクトリの直下にFoo.xsを作ったりしたいんですが,そ…

PerlでAssert

Perl5.9の時点では,assersionsと-Aコマンドラインスイッチという仕組みでCのassert(3)のようなことができるようになるはずだったらしい。しかし,そのメカニズムはPerl5.10には結局採用されなかった。 開発中はassert()が欲しい,しかし,リリース後の実行…

parrot 0.8.0 released

parrot-0.8.0 /NEWSうーん…面白そうだけどどこから何を読み始めればいいやら。

Module::Starter -> Module::Setup

モジュール作成にModule::Setupを使うようにしたらすごく便利になった! なんですが、テンプレート変数が物足りないので結局$template_varsにひとつ追加して使ってます。もしかしてテンプレート内で関数が呼べたりするのかなあ。Template-Toolkitを使ったこ…

Mooseが速いわけ

Mooseは起動に異様に時間はかかるし,クラス階層が複雑でどこから読み始めたらいいのかわからなかったのですが,使い始めるとなるほどこれはすばらしい。しかも,実行速度についてはかなり高速なんですね*1。 なぜ速いのかは追いきれてませんが,Memoizeした…

InsideOutテクニック

Perl Best Practices(PBP)でも紹介されていた,Inside-Outテクニックというものがあります。オブジェクトの完全なカプセル化が目的なわけですよ。以下,基本的な実装を示します。 # Foo.pm package Foo; use strict; use Scalar::Util qw(refaddr); my %bar_…

Perl Quiz - 解説

解答一覧(敬称略) ${^ENCODING}を使う by yappo - いきなりドン引き *is = \&isnt; by miyagawa *CORE::GLOBAL::ref/pp.cへパッチを当てる - by tokuhirom testルーチンの書き換え by wakapon - miyagawa氏のと同タイプ package ::Foo by mattn - この解答が…

Perl Quizに答えてみる

Perl Quizの出題者として一つくらいは新奇な解答を出さなければと思ってがんばってみるがなかなか難しい!とりあえずoverload::constant()に相当するコードを書けば何とかなるか,と思って試すもうまくいかない。 そこで更にコードをいじり倒していると…やっ…

Perl Quiz - package名について

Q.以下のテストケースが失敗するようなf()を書いてください。ただし,ライブラリを使用してはいけません。回答は一週間後くらいに。 #!perl -w use strict; use Test::More 'no_plan'; sub f{ # 何かする } f(); is ref(bless({}, 'Foo')), 'Foo'; __END__ s…

sv_derived_from()

5.10.0のsv_derived_from()(&UNIVERSAL::isaの実体)はもっと高速に実装できそうな気がする。 …と思って試してみると,確かに約3倍ほど速くなった。しかし,試したperlは-DDEBUGGING付きでConfigureしてあるうえ,プラットフォームがCygwinなのでこの数字は当…

Scalar::Util::Ref

instanceof演算子を実装してみた。 Scalar::Util::Ref #!perl use strict; use IO::File; use instanceof; my $x = IO::File->new(); if($x << 'IO::Handle'){ print "$x is an instance of 'IO::Handle'\n"; } __END__ Scalar::Util::blessed()&isa()と比べ…

Acme::Don't 2.0!

Acme::Don'tというモジュールがある。これが提供するdon't{}は,Perl組み込みのdo{}とは逆に,ブロックの中身を実行しない。たとえば以下のコードのように使う*1。 use Acme::Don't; don't{ print "Hello, world!\n"; # => 実行されない }; これは問題ない。…

instanceof演算子(2)

Perlのinstanceof演算子のベストプラクティスは何か Cygwinで試すとref_evalよりscalar_utilが遅かったんですが一般的にはそうでもないようです。 Linux/Perl 5.8.5で試してみると確かにref_evalよりscalar_utilのほうが早い傾向にあります。 For Foo=HASH(0…

instanceof演算子

Perlにinstanceof演算子があればいいのにと思うことがたまにある。 $xがオブジェクトで,$classのインスタンスであれば真を返す演算子だ。 既存のコードではなかなか一発でできない。 $x->isa($class); # (1) ref($x) && eval{ $x->isa($class} }; # (2) Sca…

Perlの最適化器

perlgutsとperlhackによれば,Perlの最適化は3段階あるらしい。 check routines context propagation peephole optimization 今までやってきたPL_checkによるカスタマイズはこのcheck routinesフェイズのことだったようだ。 check routinesはOPコードの生成…

warnings::unused

warnings::unused 宣言しただけで使ってない変数があると警告するプラグマを書いた。 目的としてはPerl::Critic::Policy::Variables::ProhibitUnusedVariablesと同じ。 warnings::methodと同じく,わざわざ別コマンドを走らせる必要はないうえ,実行速度にも…

macro.pm v0.04

以前のmacro.pmではマクロをdo{ ... }で囲んで展開していたのだが,マクロの中身が+(...)に展開できそうなときは+(...)に展開するように最適化したらだいぶ速くなった。 以下はperl v5.8.5 built for i386-linux-thread-multiで計った結果。 $ perl -Mblib e…

Language::P - Perl5によるPerl5の実装

http://search.cpan.org/dist/Language-P/なんだか面白そうだ。あとで読もう。

feature::compat

warnings::compatがあるのだから,feature::compatもあっていいのではないかと思う。 しかし,say()は簡単に実装できるが,switch()とstate()はソースフィルタが必要だし,あまり実用的ではないか。

warnings::lint

コンパイル後のOP treeを見て小言を言ってくれるモジュールとしては既にB::Lintというものがあるわけだが,どうせ大したチェックをしてくれるわけでもないので,いちいちperl -MO=Lint script.plなんてしていられない。 しかし,warnings::lintというプラグ…

OP_GVの実際の型

warnings::methodがスレッドのない環境で動かなかったのは,OP_GVの型がUSE_ITHREADSの有無で変わるからだった。 /* op.c as of 5.10.0 */ OP * Perl_newGVOP(pTHX_ I32 type, I32 flags, GV *gv) { dVAR; assert(gv); #ifdef USE_ITHREADS GvIN_PAD_on(gv);…

warnings::methodのメカニズム

warnings::method なぜかスレッドが無効になっている環境ではテストが通らないようだが,とりあえず公開した。 さてメカニズムだが,まずどんなOPコードが生成されるのかを目視したうえで,どのようにOPコードツリーを走査するのか考える。 $ perl -MO=Conci…

macro.pm v0.03

macro.pmはv0.03になってわりとうまく動くようになった(と思う)。ためしにHTML::FillInForm::Liteでいくつかの関数をマクロ化してベンチマークをとったところ,約20%ほど高速になった。それなりに効果はあるようだ。 ちなみに,マクロの書き方はサブルーチ…

:method attributeの有効活用

サブルーチンに付けられる:methodアトリビュートは,メソッドを定義するときに付加することで,同名の組み込み関数を呼び出すときの"Ambiguous call"警告を避けることができる。 #!perl -w sub length :method{ 1 } # 以下の文は:methodがないと"Ambiguous c…