Hatena::ブログ(Diary)

Islands in the byte stream

2012-03-06

RubyのMethod#source_locationをPerlで

[追記]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_location;
__END__
# result:
["/usr/local/lib/ruby/2.0.0/fileutils.rb", 180]

Perl版:

#!/usr/bin/env perl
use strict;
use warnings;

use B ();

sub UNIVERSAL::source_location_for {
    my($self, $method) = @_;
    my $entity = $self->can($method) or return;
    my $gv     = B::svref_2object($entity)->GV;
    return($gv->FILE, $gv->LINE);
}

use File::Spec;
use Data::Dumper;
print Dumper [ File::Spec->source_location_for('canonpath') ];
__END__
# result:
$VAR1 = [
          '/Users/gfx/perl5/perlbrew/perls/perl-5.14.2/lib/5.14.2/darwin-2level/File/Spec/Unix.pm',
          71
        ];

生の構造体を直接触る感じがPerlらしくていいですね!

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/gfx/20120306/1331047772