タグ

ブックマーク / gfx.hatenadiary.org (21)

  • A REPL command for golang - use GFx::WebLog;

    Go をちょっと試すのに便利な wrapper 二題(by id:sfujiwara)に触発されて,REPLを行うラッパースクリプトを書いてみた。 http://github.com/gfx/golang-interpreter/blob/master/g 以下のように,mainなどを書くことなく実行できる。 $ ./g go> fmt.Print("Hello, world") Hello, world go> fmt.Print(math.Fabs(-42)) 42 go> ^D $ 必要なライブラリは自動的にimportしてくれるはずだ。ただし,いまのところ関数は定義できず,行の継続もできない。こうなるとヒストリや補完機能がほしいが,それらも未実装である。 ちなみに,このgコマンドはファイル名と引数を与えて普通のインタプリタのように使うこともできる。 urged by @tokuhi

    A REPL command for golang - use GFx::WebLog;
  • A note on smart match op: $var ~~ constant vs. $var1 ~~ $var2 - Islands in the byte stream (legacy)

    先日『初めてのPerl 第5版』を少し読んだところ,スマートマッチ演算子についての解説があった。 perlsyn/Smart matching in detailをみると非常に複雑な印象を受けるが,実際にはそれほど複雑ではないようだ。むしろ,うまく使うと非常に便利である。 ただし,スマートマッチ演算子を使うときは,常に変数と定数を比較するようにしたほうがよい。 以下,使用例と問題例を示す。 #!perl -w use strict; use feature 'say'; my $foo; # $foo eq "foo" と同じ # ただし$fooがundefでも警告がでない say $foo ~~ "foo"; # $foo =~ /foo/ と同じ # ただし$fooがundefでも警告がでない say $foo ~~ qr/foo/; # 以下の挙動に注意! $foo = '00';

    A note on smart match op: $var ~~ constant vs. $var1 ~~ $var2 - Islands in the byte stream (legacy)
  • Type as State, Coercion as Hook - Islands in the byte stream (legacy)

    MooseのTypeConstraintは,型というよりはあるデータの性質を表現したものだと考えられる。また,TypeCoercionは,ある型(=あるデータの性質)に対してフックを掛けるメカニズムと考えられる。 このように考えると,Coercionを利用していろいろと面白いことができるのではないかと思う。 たとえば,以下のようにCoercionを利用してエンコーディングを推測することができる*1。 #!perl package E; use Any::Moose; use Any::Moose '::Util::TypeConstraints'; use Encode qw(encode decode FB_QUIET); subtype 'UniStr', as 'Str', where { utf8::is_utf8($_) }; # define types represent a

    Type as State, Coercion as Hook - Islands in the byte stream (legacy)
  • To repeat testing with different configuration - Islands in the byte stream (legacy)

    構成条件を変えてテストを繰り返したいことがある。 たとえば,XSとPurePerlの両方の実装を持つモジュールなどはそうだし,Any::Mooseを使ったモジュールであれば $ENV{ANY_MOOSE} を変えてテストを繰り返したいと考えるのは当然だ。 この問題は,postamble()*1でMakefileにターゲットを追加することで解決できる。 さて,ここでは,開発者モードのときに $ENV{FOO_PUREPERL}=1 でテストをもう一度繰り返したいものとする。これには,Makefile.PLに以下のように記述すればよい。 # Makefile.PL use inc::Module::Install; # ... if(author_context){ # repeat testing # see also ExtUtils::MM_Any::test_via_harness()

    To repeat testing with different configuration - Islands in the byte stream (legacy)
  • Perl 5.11.0 features on the syntax - Islands in the byte stream (legacy)

    Perl 5.11.0がリリースされたので,perl5110deltaから構文的な変更をいくつか拾ってみた。 Implicit strictures "use 5.11.0" はstrictも有効にするようになった The yada yada operator ('...') 未実装の機能を示す組み込み演算子が追加された each is now more flexible my($index, $value) = each @array ができるようになった keys @array, values @arrayもできるようだ delete local delete local $foo{bar} ができるようになった なお,これらは5.12.0へ向けた変更ではあるが,必ずしも5.12.0に入るとは限らない。 See also perl5110delta.

    Perl 5.11.0 features on the syntax - Islands in the byte stream (legacy)
  • Moose::Role = #include directive + X - Islands in the byte stream (legacy)

    前提:Moose::RoleはJavaのInterfaceなんかじゃない 最近,RoleというのはCプリプロセッサの#includeディレクティブに近いもののような気がしてきた。そして+Xがメソッドのチェック有無やコンフリクトのチェックである。 たとえば,以下のようなコードを考えてみる。 #!perl package Say; use Any::Moose '::Role'; requires 'to_string'; sub say{ my($self) = @_; print $self->to_string, "\n"; } package MyClass; use Any::Moose; with 'Say'; has name => ( is => 'rw', isa => 'Str', ); sub to_string{ my($self) = @_; return $self

    Moose::Role = #include directive + X - Islands in the byte stream (legacy)
  • What I got in YAPC::Asia 2009, notes, and todo - Islands in the byte stream (legacy)

    今回初めてYAPC::Asiaに参加した。記憶が鮮明なうちに,得たもの,考えたことをメモしておく。ハッカソンにも二日目のみ参加したが,時間があまりとれず,特に成果は出せなかった。 AnyEvent/Coro AnyEvent/Coroのイメージがつかめたのはとてもよかった。特にid:mala氏の高速になる理屈はとても分かりやすかった。具体的にどのくらい高速になるか試してみたい。 Moose高速化計画 nothingmuch, rafl, SartakとMooseについて話せたのは非常によかった。Moose高速化計画の報告がYAPC前にできなかったのは失敗だったが,将来に向けていろいろ話はできた。 New syntaxes 私はDevel::Declareが実用的だとはどうしても思えなかったのだが,この考えは改めることになった。たとえば,もし5.12で新規構文を導入したとしても,Devel:

    What I got in YAPC::Asia 2009, notes, and todo - Islands in the byte stream (legacy)
  • Do not use Devel::Declare, a magical source filter. - Islands in the byte stream (legacy)

    モダンPerlの世界へようこそ 第11回でDevel::Declareが取り上げられていました。 このモジュールは確かに「スゴイ」のですが,個人的には使うべきではないと思っています。もちろん,Devel::DeclareのフロントエンドであるMethod::SignaturesやMooseX::Declareも同様です。 これはDevel::Declareというよりはソースフィルタモジュール一般に言えることですが,問題はコンパイルと実行の間にプリプロセスという処理あることです。そのため,ブラックボックスを増やすことになり,デバッグが困難になります。 また,Devel::DeclareはPerlに新しい機能を追加するためのモジュールというより,Perlの方言を書くためのモジュールといえます。 たとえば以下のコードはMooseX::DeclareのSYNOPSISからとったものです: use

    Do not use Devel::Declare, a magical source filter. - Islands in the byte stream (legacy)
  • Multi-threaded perl vs. Single-threaded perl - Islands in the byte stream (legacy)

    perl5 ithread についての個人的な見解。そして Coro について。(tokuhirom)より ithreads を有効にしてコンパイルするだけで perl インタープリタの速度が低下する[要出典] これをちょうど試そうと思っていたところなのだった。ナイスタイミング。 結論からいえば,シングルスレッドなperlはマルチスレッドなperlよりロード時間・実行時間共に10%ほど高速である。 以下詳細を記す。 まず,perlバイナリを2つ用意する。バージョンはパッチなしの5.10.0で,ビルド/実行環境はLinux 2.6.18-92.el5pae, gcc 4.3.2 20081007 (Red Hat 4.3.2-7)である。 sperl (single-threaded perl): $ ./Configure -des -Doptimize=-O3 -Dprefix=~/sp

    Multi-threaded perl vs. Single-threaded perl - Islands in the byte stream (legacy)
  • サブルーチンのアトリビュートの信頼性 - Islands in the byte stream (legacy)

    Perl 5.6.0以降にはアトリビュート(Attribute)というメカニズムがあり,変数やサブルーチンの宣言時に呼び出されるコールバックを設定できる*1。 このアトリビュートは実験的に取り入れられたのちに放置されるという不幸な運命をたどってしまい,現状では活用するのが難しい。特に,サブルーチンアトリビュートの扱いは非常に難しく,使用に際しては様々な問題がある*2。 一つの大きな問題は,アトリビュートハンドラが呼び出されるタイミングである。アトリビュートハンドラはサブルーチンオブジェクトの構築中*3に呼び出されるのだが,サブルーチンオブジェクトの構築が不完全なため,そのままではアトリビュートハンドラ内でできることはほとんどないのだ。以下のスクリプトはこのことを示す。 #!perl -w use strict; use Devel::Peek; sub MODIFY_CODE_ATTRIB

    サブルーチンのアトリビュートの信頼性 - Islands in the byte stream (legacy)
  • switch文とif連鎖の比較 - Islands in the byte stream (legacy)

    Perl 5.10.0でswitch文が導入されたことにより,ifの連鎖はもっとわかりやすい構文に書き換えられるようになった。 use feature 'switch'; given($foo){ when("bar"){ ... } when("baz"){ ... } default{ ... } } switch文の導入で便利になった一方,このwhen()で使われるマッチングは「スマートマッチ」という特殊な演算子によって行われることのコストが懸念される。 そこで,switch文とif連鎖の速度を比較してみた。 また,かつて単純なif連鎖とよく比較されたのは,ハッシュテーブルを参照する方式である。if連鎖の複雑さがO(n)なのに対し,ハッシュテーブルの参照はO(1)であるため,連鎖が長くなるとハッシュテーブルの方が高速であるとされる。『Perlベストプラクティス』では,ハッシュテーブル

    switch文とif連鎖の比較 - Islands in the byte stream (legacy)
  • Pure PerlによるPerl5 Virtual Machineの実装 - Islands in the byte stream (legacy)

    Perl VMの気持ちを知るには、PurePerlで実装してみるとよい。 コード例(PerlVM.pmのコードは記事の末尾にある): #!perl -w use strict; use PerlVM; my $x = shift || 42; PerlVM::call_sv(sub{ print "Hello,", " world!", "\n"; if($x){ print $x, " is true\n"; } else{ print $x, " is false\n"; } }); __END__ 実行結果: $ perl hello.pl Hello, world! 42 is trueむろん、PerlVM::call_sv()の中で引数を呼び出したりはしていない。 Hello, world!くらいならPerlVMの中身も比較的単純だ。そのメカニズムはBモジュールに依存している。B

    Pure PerlによるPerl5 Virtual Machineの実装 - Islands in the byte stream (legacy)
    koko1000ban
    koko1000ban 2009/04/06
    すごい..
  • B::Foreach::Iteratorでforeachイテレータを進める - Islands in the byte stream (legacy)

    B::Foreach::Iteratorというモジュールを書いた*1。 use B::Foreach::Iterator 0.02; foreach my $key(foo => 10, bar => 20, baz => 30){ printf "%s => %s\n", $key => iter->next; } iter->next()*2はforeachループのイテレータをひとつ進め、その値を返す。 また、iter->peek()はイテレータを進めることなく、次のイテレータを返す。 このモジュールを実装するにあたってpp_hot.cのpp_iter()を読んだのだが、確かにforeach ($min .. $max)は内部で配列を生成していない。また、foreach (reverse ...)についても最適化が行われており、reverse()した一時配列を作るのではなく、イテレータ

    B::Foreach::Iteratorでforeachイテレータを進める - Islands in the byte stream (legacy)
  • SYNOPSISの構文を自動でチェックする - Islands in the byte stream (legacy)

    新しいモジュールの使い方を調べるときに真っ先に目を通すのがPODのSYNOPSISセクションである。特に,英語が母語ではないPerlerにとってはPODの中で最も重要なセクションといっても過言ではない。それだけに,自らモジュールを書くときは細心の注意を払う。 ところで,その内容の構文チェックは今まで手動でやっていたのだが,Test::Weakenのテストファイルを眺めていると面白いテストがあった。synpsis.tというのがそれで,PODのSYNPISISセクションの中身を抜き出して実行するというものだ。考えてみれば,構文チェックで十分なら特別なモジュールのサポートを得なくても簡単に書くことができる。 そこで,一般化してModule::Setup用のテンプレートにしてみた。 #!perl -w use strict; use Test::More tests => 1; use [% mo

    SYNOPSISの構文を自動でチェックする - Islands in the byte stream (legacy)
  • 既存の特異メソッドモジュール - Islands in the byte stream (legacy)

    Perlで特異メソッドでは「標準モジュールにも特異メソッドを実現するものはない」と書いたが,そういえばPerl 5.10.0から標準モジュールになったObject::Accessorというものがあることを思い出した。これは直接特異メソッドを定義するのではないが,振る舞いとしては特異メソッドそのものである。実際,Class::Monadicもadd_field()というアクセサを作成する機能を提供している。 Object::AccessorのSYNOPSISより: ### using the object as base class package My::Class; use base 'Object::Accessor'; $obj = My::Class->new; # create base object $bool = $obj->mk_accessors('foo'); # cr

    既存の特異メソッドモジュール - Islands in the byte stream (legacy)
  • Perlで特異メソッド - Islands in the byte stream (legacy)

    Ruby界隈ではあたりまえのように使われる特異メソッド*1だが,Perlでは組み込みでのサポートはなく,標準モジュールにも特異メソッドを実現するものはない。Class::MOP/Mooseの匿名クラスが似た用途を持っている*2が,オブジェクトの実装型に制約がある。たとえば,以下のコードは動かない。 #!perl -w use strict; use IO::File (); use Moose (); my $anonclass = Moose::Meta::Class->create_anon_class( superclasses => [qw(IO::File)], methods => { hello => sub{ my $self = shift; $self->print("Hello, world!\n"); }, } ); my $io = $anonclass->new

    Perlで特異メソッド - Islands in the byte stream (legacy)
  • Re: XSの勉強を始めるためのエントリーポイントは? - Islands in the byte stream (legacy)

    Re: XSの勉強を始めるためのエントリーポイントは? あまり参考にならないかもしれませんが,私がXSを勉強するにあたっては,CPANのモジュールのソースコードを読むより実際に書いてみるのが一番だと思います。ただし,何か特定の目的があって,そのために関係がありそうなコードを探して読む,ということは非常によくあります。 以下,思いついたことを適当に並べてみます。 自分でコードを書いてみて初めて分かることが少なくない 学ぶのに適した理想的なコードは,そう簡単には見つからない 古い書き方やおかしな書き方をしているコードも大量にあるので,そういうコードをフィルタリングするためにも,いろいろな作者のコードを読んだほうがいい 多くのコードの中から理想的な部分を抜き出して,それを身につけていく 目的とまったく関係ないコードから閃きを得ることも多い perlのソースコードをすぐ参照できるようにしておくのは

    Re: XSの勉強を始めるためのエントリーポイントは? - Islands in the byte stream (legacy)
  • strict無効化の誤謬 - Islands in the byte stream (legacy)

    シンボルテーブルを操作するときに"no strict 'refs'"で一時的にstrictを無効化することはよくあるが,デバッグしにくいバグが紛れ込む可能性がある。 たとえば,以下のようにアクセサを動的に生成するコードはCPANのそこかしこにある。 sub make_accessor{ my($class, $property) = @_; no strict 'refs'; # simple read-only accessor *{$class. '::' . $property} = sub{ my($self) = @_; return $self->{$property}; } } このようなコードによって生成されたメソッドを,正しくオブジェクトに対して使う分には問題ない。しかし,このメソッドをクラスメソッドとして呼び出すと,グローバル変数${$self}を参照し,その値をハッシ

    strict無効化の誤謬 - Islands in the byte stream (legacy)
  • モダンなXSの書き方 - Islands in the byte stream (legacy)

    PerlのソースコードはPerl言語以上に変化が大きく,それに伴ってXSの書き方もだいぶ変わってきている。新しいAPIを使ったほうが可読性がよかったり高速だったり使いやすかったりする。 たとえば,スカラー(SV)から文字列(PV: pointer valueつまりchar*)を得るAPIの変遷は次のようになっている。 /* SV*からPVを得る古い書き方 */ STRLEN len; const char* pv = SvPV(pv, len); # pvとlen両方ほしいとき const char* pv_only = SvPV(pv, PL_na); # pvだけほしいとき /* その後SvPV_nolen()が追加され,PL_naはdeprecatedに */ const char* pv_only = SvPV_nolen(pv); /* 今は*_constが追加されたのでcons

    モダンなXSの書き方 - Islands in the byte stream (legacy)
  • Perl/XSが得意なこと - Islands in the byte stream (legacy)

    最近ひたすらXSを書いていて思ったのが,XSはやっぱり速いということ。 ただ,いつでも無条件に速いというわけでもなく,何も考えずに書くとPurePerlのコードより遅くなることも珍しくない。実際,最近書いたShikaやMOPのXS版もいきなり高速だったわけではなく,一番最初のコードはPurePerlのほうが10%-30%ほど高速だった。 いろいろベンチマークをとった結果の感触として,XSの得手・不得手が分かってきたのでメモしておく。ちなみに下記で「注意を払う」というのは内部で呼ばれるmalloc()を極力減らすという意味で使っている。SVの生成自体はmalloc()を伴わないことが多い*1が,文字列の生成/連結や配列の生成/push/unshiftでは内部でmalloc()が呼ばれる可能性が高く,速度を落とす原因となる。 得手分野 ループ - XSのループが早いというより,Perlのループ

    Perl/XSが得意なこと - Islands in the byte stream (legacy)