C::P::FV::AutoのCatalyst 5.8対応パッチを書いた
typesterさん謹製のC::P::FV::Autoはとっても便利なのですが、例に漏れず5.8対応されていません。で、意外とニーズがあるようなのでさくっとpatch書いてみました。(といってもMRO::Compat化したくらいですが…)
ただ、sub forwardでlocal $NEXT::NEXT{}してるのがちと意味がわからなかったのと代替案が思いつかなかったのでざっくり削ってます。Changes見る限りnestしたforwardの対応っぽいのですが、ごめんなさい。よくわからんかったです。
一応それのテストであろう06_nexted_actions.tに通ってはいるのですが、この辺は教えてエロい人ってことでよろしくです。
初めてのDevel::BindPP
Standard C++
foo-bar.cpp
#include <iostream> int main () { std::cout << "Hello World"; }
$ gcc -o foo-bar foo-bar.cpp -lstdc++ $ foo-bar Hello Wolrd
Devel::BindPP
$ perl -MDevel::BindPP -e 'use Devel::BindPP::WriteFile()'
foo-bar.cpp
include <iostream> #include "bindpp.h" XS(xs_hello_world) { std::cout << "Hello World"; } extern "C" { XS(boot_Foo__Bar) { pl::BootstrapCtx bc; pl::Package pkg("Foo::Bar", __FILE__); pkg.add_method("hello_world", xs_hello_world); } };
MakeFile.pl
use inc::Module::Install; name 'Foo-Bar'; all_from 'lib/Foo/Bar.pm'; makemaker_args( OBJECT => '$(O_FILES)', LIBS => ['-lstdc++'], ); WriteAll;
lib/Foo/Bar.pm
package Foo::Bar; use strict; use warnings; our $VERSION = '0.00001'; use XSLoader; XSLoader::load __PACKAGE__, $VERSION; 1;
$ perl MakeFile.pl $ make $ perl -Mblib -MFoo::Bar -e 'Foo::Bar::hello_world' HelloWorld
MooseのマニュアルとTPF
Moose Docs Grant Is Complete – House Absolute(ly) Pointless
http://cpansearch.perl.org/src/DROLSKY/Moose-0.74/Changes
0.66 Tue, February 3, 2009
* Moose::Manual
- This is a brand new, extensive manual for Moose. This aims to
provide a complete introduction to all of Moose's
features. This work was funded as part of the Moose docs grant
from TPF. (Dave Rolsky)
Moose::ManualってTPFの助成が出てたんですね。そーいえば、そうだったかも。
で、TPF-Jが助成して翻訳する流れと。なるほど。
for(;;)とforeach()とLoop unrollingと
YappoLogs: CPUの気持ちは大事だけど、VMの気持ちも考えようよ
http://d.hatena.ne.jp/yappo/20090330/1238360153
会議中なので-MO=Consiseしてないし特に言いたいことはない。
use strict; use warnings; use Benchmark qw(:all); cmpthese( timethese( 0, { loop_for => sub { my $sum = 0; for (my $i = 0; $i < 100; $i++) { $sum = $sum + $i; } }, loop_foreach => sub { my $sum = 0; for my $i (0 .. 99) { $sum = $sum + $i; } }, loop_unrolling_5 => sub { my $sum = 0; for (my $i = 0; $i < 100; $i += 5) { $sum = $sum + $i + 0; $sum = $sum + $i + 1; $sum = $sum + $i + 2; $sum = $sum + $i + 3; $sum = $sum + $i + 4; } }, loop_unrolling_10 => sub { my $sum = 0; for (my $i = 0; $i < 100; $i += 10) { $sum = $sum + $i + 0; $sum = $sum + $i + 1; $sum = $sum + $i + 2; $sum = $sum + $i + 3; $sum = $sum + $i + 4; $sum = $sum + $i + 5; $sum = $sum + $i + 6; $sum = $sum + $i + 7; $sum = $sum + $i + 8; $sum = $sum + $i + 9; } }, loop_unrolling_50 => sub { my $sum = 0; for (my $i = 0; $i < 100; $i += 50) { $sum = $sum + $i + 0; $sum = $sum + $i + 1; $sum = $sum + $i + 2; $sum = $sum + $i + 3; $sum = $sum + $i + 4; $sum = $sum + $i + 5; $sum = $sum + $i + 6; $sum = $sum + $i + 7; $sum = $sum + $i + 8; $sum = $sum + $i + 9; $sum = $sum + $i + 10; $sum = $sum + $i + 11; $sum = $sum + $i + 12; $sum = $sum + $i + 13; $sum = $sum + $i + 14; $sum = $sum + $i + 15; $sum = $sum + $i + 16; $sum = $sum + $i + 17; $sum = $sum + $i + 18; $sum = $sum + $i + 19; $sum = $sum + $i + 20; $sum = $sum + $i + 21; $sum = $sum + $i + 22; $sum = $sum + $i + 23; $sum = $sum + $i + 24; $sum = $sum + $i + 25; $sum = $sum + $i + 26; $sum = $sum + $i + 27; $sum = $sum + $i + 28; $sum = $sum + $i + 29; $sum = $sum + $i + 30; $sum = $sum + $i + 31; $sum = $sum + $i + 32; $sum = $sum + $i + 33; $sum = $sum + $i + 34; $sum = $sum + $i + 35; $sum = $sum + $i + 36; $sum = $sum + $i + 37; $sum = $sum + $i + 38; $sum = $sum + $i + 39; $sum = $sum + $i + 40; $sum = $sum + $i + 41; $sum = $sum + $i + 42; $sum = $sum + $i + 43; $sum = $sum + $i + 44; $sum = $sum + $i + 45; $sum = $sum + $i + 46; $sum = $sum + $i + 47; $sum = $sum + $i + 48; $sum = $sum + $i + 49; } }, loop_unrolling_100 => sub { my $sum = 0; for (my $i = 0; $i < 100; $i += 100) { $sum = $sum + $i + 0; $sum = $sum + $i + 1; $sum = $sum + $i + 2; $sum = $sum + $i + 3; $sum = $sum + $i + 4; $sum = $sum + $i + 5; $sum = $sum + $i + 6; $sum = $sum + $i + 7; $sum = $sum + $i + 8; $sum = $sum + $i + 9; $sum = $sum + $i + 10; $sum = $sum + $i + 11; $sum = $sum + $i + 12; $sum = $sum + $i + 13; $sum = $sum + $i + 14; $sum = $sum + $i + 15; $sum = $sum + $i + 16; $sum = $sum + $i + 17; $sum = $sum + $i + 18; $sum = $sum + $i + 19; $sum = $sum + $i + 20; $sum = $sum + $i + 21; $sum = $sum + $i + 22; $sum = $sum + $i + 23; $sum = $sum + $i + 24; $sum = $sum + $i + 25; $sum = $sum + $i + 26; $sum = $sum + $i + 27; $sum = $sum + $i + 28; $sum = $sum + $i + 29; $sum = $sum + $i + 30; $sum = $sum + $i + 31; $sum = $sum + $i + 32; $sum = $sum + $i + 33; $sum = $sum + $i + 34; $sum = $sum + $i + 35; $sum = $sum + $i + 36; $sum = $sum + $i + 37; $sum = $sum + $i + 38; $sum = $sum + $i + 39; $sum = $sum + $i + 40; $sum = $sum + $i + 41; $sum = $sum + $i + 42; $sum = $sum + $i + 43; $sum = $sum + $i + 44; $sum = $sum + $i + 45; $sum = $sum + $i + 46; $sum = $sum + $i + 47; $sum = $sum + $i + 48; $sum = $sum + $i + 49; $sum = $sum + $i + 50; $sum = $sum + $i + 51; $sum = $sum + $i + 52; $sum = $sum + $i + 53; $sum = $sum + $i + 54; $sum = $sum + $i + 55; $sum = $sum + $i + 56; $sum = $sum + $i + 57; $sum = $sum + $i + 58; $sum = $sum + $i + 59; $sum = $sum + $i + 60; $sum = $sum + $i + 61; $sum = $sum + $i + 62; $sum = $sum + $i + 63; $sum = $sum + $i + 64; $sum = $sum + $i + 65; $sum = $sum + $i + 66; $sum = $sum + $i + 67; $sum = $sum + $i + 68; $sum = $sum + $i + 69; $sum = $sum + $i + 70; $sum = $sum + $i + 71; $sum = $sum + $i + 72; $sum = $sum + $i + 73; $sum = $sum + $i + 74; $sum = $sum + $i + 75; $sum = $sum + $i + 76; $sum = $sum + $i + 77; $sum = $sum + $i + 78; $sum = $sum + $i + 79; $sum = $sum + $i + 80; $sum = $sum + $i + 81; $sum = $sum + $i + 82; $sum = $sum + $i + 83; $sum = $sum + $i + 84; $sum = $sum + $i + 85; $sum = $sum + $i + 86; $sum = $sum + $i + 87; $sum = $sum + $i + 88; $sum = $sum + $i + 89; $sum = $sum + $i + 90; $sum = $sum + $i + 91; $sum = $sum + $i + 92; $sum = $sum + $i + 93; $sum = $sum + $i + 94; $sum = $sum + $i + 95; $sum = $sum + $i + 96; $sum = $sum + $i + 97; $sum = $sum + $i + 98; $sum = $sum + $i + 99; } }, noloop => sub { my $sum = 0; $sum = $sum + 0; $sum = $sum + 1; $sum = $sum + 2; $sum = $sum + 3; $sum = $sum + 4; $sum = $sum + 5; $sum = $sum + 6; $sum = $sum + 7; $sum = $sum + 8; $sum = $sum + 9; $sum = $sum + 10; $sum = $sum + 11; $sum = $sum + 12; $sum = $sum + 13; $sum = $sum + 14; $sum = $sum + 15; $sum = $sum + 16; $sum = $sum + 17; $sum = $sum + 18; $sum = $sum + 19; $sum = $sum + 20; $sum = $sum + 21; $sum = $sum + 22; $sum = $sum + 23; $sum = $sum + 24; $sum = $sum + 25; $sum = $sum + 26; $sum = $sum + 27; $sum = $sum + 28; $sum = $sum + 29; $sum = $sum + 30; $sum = $sum + 31; $sum = $sum + 32; $sum = $sum + 33; $sum = $sum + 34; $sum = $sum + 35; $sum = $sum + 36; $sum = $sum + 37; $sum = $sum + 38; $sum = $sum + 39; $sum = $sum + 40; $sum = $sum + 41; $sum = $sum + 42; $sum = $sum + 43; $sum = $sum + 44; $sum = $sum + 45; $sum = $sum + 46; $sum = $sum + 47; $sum = $sum + 48; $sum = $sum + 49; $sum = $sum + 50; $sum = $sum + 51; $sum = $sum + 52; $sum = $sum + 53; $sum = $sum + 54; $sum = $sum + 55; $sum = $sum + 56; $sum = $sum + 57; $sum = $sum + 58; $sum = $sum + 59; $sum = $sum + 60; $sum = $sum + 61; $sum = $sum + 62; $sum = $sum + 63; $sum = $sum + 64; $sum = $sum + 65; $sum = $sum + 66; $sum = $sum + 67; $sum = $sum + 68; $sum = $sum + 69; $sum = $sum + 70; $sum = $sum + 71; $sum = $sum + 72; $sum = $sum + 73; $sum = $sum + 74; $sum = $sum + 75; $sum = $sum + 76; $sum = $sum + 77; $sum = $sum + 78; $sum = $sum + 79; $sum = $sum + 80; $sum = $sum + 81; $sum = $sum + 82; $sum = $sum + 83; $sum = $sum + 84; $sum = $sum + 85; $sum = $sum + 86; $sum = $sum + 87; $sum = $sum + 88; $sum = $sum + 89; $sum = $sum + 90; $sum = $sum + 91; $sum = $sum + 92; $sum = $sum + 93; $sum = $sum + 94; $sum = $sum + 95; $sum = $sum + 96; $sum = $sum + 97; $sum = $sum + 98; $sum = $sum + 99; } } ) );
Benchmark: running loop_for, loop_foreach, loop_unrolling_10, loop_unrolling_100, loop_unrolling_5, loop_unrolling_50, noloop for at least 3 CPU seconds... loop_for: 3 wallclock secs ( 3.16 usr + 0.00 sys = 3.16 CPU) @ 41487.34/s (n=131100) loop_foreach: 3 wallclock secs ( 3.17 usr + 0.00 sys = 3.17 CPU) @ 53420.19/s (n=169342) loop_unrolling_10: 3 wallclock secs ( 3.14 usr + 0.00 sys = 3.14 CPU) @ 42575.48/s (n=133687) loop_unrolling_100: 4 wallclock secs ( 3.14 usr + 0.00 sys = 3.14 CPU) @ 43949.04/s (n=138000) loop_unrolling_5: 3 wallclock secs ( 3.09 usr + 0.00 sys = 3.09 CPU) @ 37364.72/s (n=115457) loop_unrolling_50: 3 wallclock secs ( 3.13 usr + 0.00 sys = 3.13 CPU) @ 44089.46/s (n=138000) noloop: 4 wallclock secs ( 3.21 usr + 0.00 sys = 3.21 CPU) @ 96098.44/s (n=308476) Rate loop_unrolling_5 loop_for loop_unrolling_10 loop_unrolling_100 loop_unrolling_50 loop_foreach noloop loop_unrolling_5 37365/s -- -10% -12% -15% -15% -30% -61% loop_for 41487/s 11% -- -3% -6% -6% -22% -57% loop_unrolling_10 42575/s 14% 3% -- -3% -3% -20% -56% loop_unrolling_100 43949/s 18% 6% 3% -- -0% -18% -54% loop_unrolling_50 44089/s 18% 6% 4% 0% -- -17% -54% loop_foreach 53420/s 43% 29% 25% 22% 21% -- -44% noloop 96098/s 157% 132% 126% 119% 118% 80% --
ソースフィルタを使わないでtry/catchを提供してくれるTryCatch
http://marcus.nordaaker.com/2009/03/a-proper-trycatch-for-perl/
メモ 後で書く
{ package HTTPStatus; use Moose; has code => (is => 'rw', isa => 'Int', required => 1); __PACKAGE__->meta->make_immutable; } use strict; use warnings; use TryCatch; sub foo { my $code = shift; try { die HTTPStatus->new(code => $code); } catch (HTTPStatus $e where {$_->code >= 400 && $_->code < 500}) { return '4xx client error'; } catch (HTTPStatus $e where {$_->code >= 500 && $_->code < 600}) { return '5xx server error'; } catch (HTTPStatus $e where {$_->code < 200 || $_->code >= 600}) { return 'Unknown error'; } return 'ok'; } warn foo(200); #ok warn foo(500); #'5xx server error
Delegationを使わないでNon-Mooseクラスを継承
FAQにもあるけど、Moose::Objectも継承して->meta->new_objectを明示的に呼ぶことにより、delegationを使わないでNon-Mooseクラスを継承することもできる。
use strict; use warnings; { package Parent; sub new { my ($class, %args) = @_; bless {name => $args{name}}, $class; } } { package Child; use Moose; extends qw(Parent Moose::Object); no Moose; sub new { my $class = shift; my $obj = $class->SUPER::new(@_); return $class->meta->new_object( __INSTANCE__ => $obj, @_, ); } __PACKAGE__->meta->make_immutable; } my $obj = Child->new(name => 'foo'); warn $obj->{name};
こんな感じだけど、Parentがuse fieldsしてる場合にはやっぱりdelegationを使わないとダメなそうだ。
use strict; use warnings; { package Parent; use fields qw(name); sub new { my ($class, %args) =@_; my $self = ref $class ? $class : fields::new($class); $self->{name} = $args{name}; $self; } } ...
こんな感じにParentがuse fieldsしてると
Pseudo-hashes are deprecated at subclass.pl line 10. No such pseudo-hash field "name" at subclass.pl line 10.
と怒られる。
jrockway曰くfieldsの非互換性をMooseで知る術がないからだそうな。
ぶっちゃけfieldsが何やってんのかよくわかってないのでそーゆーもんだと覚えた。
Non-MooseクラスをDelegationを使って継承
久々にMoose書こうとしたら酷いことになってたのでリハビリ開始。
Non-Mooseなクラスを継承する時には委譲を使うのは知ってたけどコンストラクタも継承するとこんな感じ?
自信なす><
{ package Parent; use strict; use warnings; sub new { my ($class, %args) = @_; bless {%args}, $class; } sub name { my ($self, $name) = @_; $self->{name} = $name if $name; return $self->{name}; } package Child; use Moose; has parent => ( is => 'ro', isa => 'Parent', handles => [qw/name/], ); no Moose; sub BUILDARGS { my ($class, %args) = @_; $args{parent} = Parent->new(%args); return {%args}; } __PACKAGE__->meta->make_immutable; } my $child = Child->new(name => 'hoge'); warn $child->name;