タグ

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

  • RubyのMethod#source_locationをPerlで - Islands in the byte stream (legacy)

    [追記]Cside先生がUNIVERSAL::source_location_forとしてリリースしておりますのでcpanmでご利用ください![/追記] asakusa.rbでsource_locationというメソッドを教えてもらいました。 それによれば、Rubyのメソッドオブジェクト(UnbountMethod, Method, Procなど)にはsource_locationというメソッドがあり、そのメソッドが定義されたファイル名と行番号を取得することができます。これはクラス階層が複雑なときにデバッグに役立ちそうです。 Perlでも標準ライブラリに含まれるBモジュールを使って同様のことができるのでやってみました。 Ruby版: #!/usr/bin/env ruby2 require 'fileutils'; p FileUtils.method(:pwd).source_locat

    RubyのMethod#source_locationをPerlで - Islands in the byte stream (legacy)
    hirafoo
    hirafoo 2012/03/07
    source_location
  • 常識を覆すソートアルゴリズム!その名も"sleep sort"! - Islands in the byte stream (legacy)

    TwitterのTLで知ったのだが、少し前に海外掲示板で"sleep sort"というソートアルゴリズムが発明され、公開されたようだ。このアルゴリズムが面白かったので紹介してみる。 Genius sorting algorithm: Sleep sort 1 Name: Anonymous : 2011-01-20 12:22 諸君!オレは天才かもしれない。このソートアルゴリズムをみてくれ。こいつをどう思う? #!/bin/bash function f() { sleep "$1" echo "$1" } while [ -n "$1" ] do f "$1" & shift done wait example usage: ./sleepsort.bash 5 3 6 3 6 3 1 4 7 2 Name: Anonymous : 2011-01-20 12:27 >>1 なん…だと

    常識を覆すソートアルゴリズム!その名も"sleep sort"! - Islands in the byte stream (legacy)
  • Crazy module end markers - Islands in the byte stream (legacy)

    先日Classic::Perlというモジュールで奇妙なモジュール終末値*1を見た。 # snip __THE__ => __END__ =head1 NAME この発想はなかった。=>演算子の左辺は裸のワードでよく、しかも演算子の右辺は省略できる*2ため、これは単にリテラルの"__THE__"の後、__END__で通常通りスクリプトの終わりを宣言しているのである。 面白いことを考える人がいるものだ。 *1:真ならなんでもよい *2:つまり、foo(bar =>)という構文が許される。,演算子から類推すると理解できると思う。

    Crazy module end markers - Islands in the byte stream (legacy)
    hirafoo
    hirafoo 2010/05/27
  • XSでメモリークを避けるたった一つの方法 - Islands in the byte stream (legacy)

    XSでメモリリークを避ける基原則は、それほど難しくない。すなわち、作ったSV(およびSVファミリ)はすぐsv_2mortal()するのである。mortalなSVはスコープ*1から抜けるときに解放されるため、メモリリークは起こらない。つまり、あるスコープ内で新しく作ったすべてのSVをmortalな状態にしておくということだ。 この原則のもとでコードを書くと、誤ってリファレンスカウントを増やさなかったケースでは警告が頻繁に起きる。しかし、少なくともメモリリークは起こらない*2。メモリリークの検出は難しいので、警告が出るのは福音であろう。 もちろんこれは原則で、メモリリークにまつわることで覚えなければならないことは決して少なくない。 たとえば、XSUBの戻り値をSV*にするとき、sv_2mortal(RETVAL)してはいけない。これはPerlの仕様ではなくxsubppが勝手にsv_2mort

    XSでメモリークを避けるたった一つの方法 - Islands in the byte stream (legacy)
  • File::Spec::Memoized - Makes File::Spec faster - Islands in the byte stream (legacy)

    File::Specはファイルパスを扱うために欠かせないモジュールだが,メソッドによっては非常に遅くプログラムのボトルネックになりかねない。 このようなケースでは,メモイズ(Memoize)というテクニックが役に立つ。メモイズは,引数が単純で副作用を持たない関数の結果をキャッシュして高速化する手法である*1。 メモ化(Memoization) - Wikipedia たとえば,重い処理を行うf()があったとして,そのf()の結果が特定の引数に対して一意に決まり,かつf()に副作用がないとき,以下のように結果をキャッシュしたmemozied_f()を用意したとしても,f()とmemozied_f()の意味は変わらないが,memoized_f()の二度目以降の呼び出しがf()の呼び出しよりも高速になる。 my %cache; sub memoized_f{ # 引数からIDを作成する my $

    File::Spec::Memoized - Makes File::Spec faster - Islands in the byte stream (legacy)
    hirafoo
    hirafoo 2010/01/06
  • Use -w in applications, use warnings in modules - Islands in the byte stream (legacy)

    警告のためには -w ではなく use warnings を使うべき,という意見がある*1。 perl - use warnings; # -w でなくて - 404 Blog Not Found 現代的なPerlの記述方法一覧 + α - Perl入門〜サンプルコードによるPerl入門〜 しかしそれはある意味では正解だが,ある意味では間違いである。正しくは「アプリケーションでは #!行に-wと書き,モジュールではuse warningsを使う」である。 以下のコードではそれを示す。 (1) $ perl -MFile::Spec -E 'say File::Spec->join("foo", undef)' foo/ $ (2) $ perl -MFile::Spec -wE 'say File::Spec->join("foo", undef)' Use of uninitialize

    Use -w in applications, use warnings in modules - Islands in the byte stream (legacy)
    hirafoo
    hirafoo 2009/11/05
  • The history of wantarray() - Islands in the byte stream (legacy)

    void context + BEGIN の horror 的ななにかで指名されたので答えるよ。 疑問点をまとめると以下の二点ということでいいですか。 なぜ特殊コードブロックの呼び出しコンテキストは不定とされているのか なぜ特殊コードブロックが実際にはスカラーコンテキストで呼ばれるのか 結論からいうと,第一の疑問の答えは,特殊コードブロックを呼び出すcall_list()内のcall_sv()においてコンテキストフラグを与えていないからです。第二の疑問の答えは,call_sv()のデフォルトコンテキストがG_SCALARだからです。 まずそもそもwantarray()の歴史を振り返ると,初期のPerlにはvoid contextは存在しなかったわけですよ。 Perl 5.003_07のperlfunc -f wantarray: Returns TRUE if the context of

    The history of wantarray() - Islands in the byte stream (legacy)
    hirafoo
    hirafoo 2009/06/05
  • 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)
  • リスト代入の不思議 - Islands in the byte stream (legacy)

    スカラーの代入 { x = y } が左辺値そのものを返すというのは分かりやすい。 しかし,リスト代入 { (x) = (y) } が返す値は左辺値ではない。というか,現在の実装は挙動が不安定でバグもある。 左辺値を返すように見える例: #!perl use feature 'say'; say scalar do{ my @a = (1 .. 10) }; # => 10 (要素数) say join(' ', do{ my @a = (1..3) }; # => 1 2 3 (リスト) __END__ ちょっと変な例: #!perl use feature 'say'; say scalar do{ my %h = (a => 1, b => 2) }; # => 4 (要素数?) # 比較 my %h = (a => 1, b => 2); say scalar %h; # => 2

    リスト代入の不思議 - Islands in the byte stream (legacy)
    hirafoo
    hirafoo 2009/04/18
  • 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)
  • Test::LeakTrace 0.07 - Islands in the byte stream (legacy)

    Devel::LeakTraceもそうだが,0.07以前のTest::LeakTraceは不可解な値を報告することがあった。 $ perl -MDevel::LeakTrace::Fast -e 'my $a; my $b = \$a' leaked SV(0x0x8f87dd8) from -e line 1 leaked SV(0x0x8f87c94) from -e line 1 $ perl -MTest::LeakTrace::Script -le -e 'my $a; my $b = \$a' leaked SCALAR(0x9f4cdd8) from -e line 1. $ 「Test::LeakTraceをCPANにあげた」の記事でも,目的の相互参照だけでなく,空のハッシュが報告されている。 長らくこれが何なのか分からなかったのだが,この現象のメカニズムをどうやら特定でき

    Test::LeakTrace 0.07 - Islands in the byte stream (legacy)
  • 1