Emacs: perlのモジュールの関数一覧をバッファに表示

;;; you need ..
;;; YAML::Syck
;;; Class::Inspector

(defun perl-class-inspector-functions (class)
  (interactive)
  (let
      ((buffer-name (concat "*functions " class "*")))
    (if (get-buffer buffer-name)
        (progn
          (set-buffer buffer-name))
      (progn
        (shell-command
         (concat 
          "perl -MClass::Inspector -MYAML::Syck -e"
          "'use " class "; print Dump(Class::Inspector->functions('" class "')) '"))
        (set-buffer "*Shell Command Output*")
        (rename-buffer buffer-name)))))

(defun perl-class-inspector-functions-at-point ()
  (interactive)
  (perl-class-inspector-functions (cperl-word-at-point)))

EmacsPerlを編集中に、「あー◯◯のモジュールに入ってる関数一覧を表示したい」って感じの時に使う。例えば「LWP::UserAgent」の関数一覧を表示したいのなら、Emacsのバッファ内で「LWP::UserAgent」にカーソルを合わせて M-x perl-class-inspector-functions-at-point をすると

--- 
- _agent
- _need_proxy
- _new_response
- _process_colonic_headers
- _request_sanity_check
- agent
- clone
- conn_cache
- cookie_jar
- credentials
- default_header
- default_headers
- env_proxy
- from
- get
- get_basic_credentials
- head
- is_protocol_supported
- max_redirect
- max_size
- mirror
- new
- no_proxy
- parse_head
- post
- prepare_request
- protocols_allowed
- protocols_forbidden
- proxy
- redirect_ok
- request
- requests_redirectable
- send_request
- simple_request
- timeout
- use_alarm
- use_eval

*functions LWP::UserAgent*

こんな感じの出力が出る。簡単なリファレンスとして、もしくはdabbrev(動的な略称展開)の候補として使うのに有効かなぁ。

禿げしく「それ M-x cperl-perldoc-at-point でよくね?」なんだけど、perldoc開くとdabbrevする時に全然関係ない単語も候補に含まれるようになってしまっていやーん な時もあるかなぁと。


実際に役に立ってくれるかどうかはまだ未検証....

 

Class::Inspector

関数の一覧を生成するのにClass::Inspectorというモジュールを使ってます。リフレクション/イントロスペクション? なモジュール。これが無いと動かないです。

どうやって関数のリストを作ってるんだろうとClass::Inspectorのソースを見たら

sub functions {
	my $class = shift;
	my $name  = $class->_class(shift) or return undef;
	return undef unless $class->loaded( $name );

	# Get all the CODE symbol table entries
	my @functions = sort grep { /$RE_IDENT/o }
		grep { defined &{"${name}::$_"} }
		keys %{"${name}::"};
	?@functions;
}

肝はこの部分だけだった。シンプルだね。ロードしたクラスのシンボルテーブルからCODEだけ抜き出してる。