0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

関数/メソッドの定義を取り出す方法

Last updated at Posted at 2019-12-27

juliaのソースファイルを分析し、関数呼出しの木を作ろうとしたことがあったわけです。https://github.com/sazare/parsetools/blob/master/src/parsetool.jl

そんな中、ソースファイルでなく、メモリ上でincludeされた関数の定義はとってこれないのか、ずっと悩んでいたが、すこしわかったので書いておく。
完全にはわかっていない。(大変だということはわかった)

まず、このリポジトリにある関数parsefileが定義してあるとする。

julia> mm=methods(parsefile)
# 1 method for generic function "parsefile":
[1] parsefile(fname) in Main at 
/parsetool.jl:58

julia> typeof(mm)
Base.MethodList

help?> Base.MethodList
  No documentation found.

  Summary
  ≡≡≡≡≡≡≡≡≡

  mutable struct Base.MethodList <: Any

  Fields
  ≡≡≡≡≡≡≡≡

  ms :: Array{Method,1}
  mt :: Core.MethodTable

このmsとmtをたどっていくと、mtのほうに定義が残っていた。


julia> mm.mt
# 1 method for generic function "parsefile":
[1] parsefile(fname) in Main at 
/parsetool.jl:58

julia> typeof(mm.mt)
Core.MethodTable

help?> Core.MethodTable
  No documentation found.

  Summary
  ≡≡≡≡≡≡≡≡≡

  mutable struct Core.MethodTable <: Any

  Fields
  ≡≡≡≡≡≡≡≡

  name      :: Symbol
  defs      :: Any
  cache     :: Any
  max_args  :: Int64
  kwsorter  :: Any
  module    :: Module
  backedges :: Array{Any,1}
            :: Int64
            :: Int64
  offs      :: UInt8
            :: UInt8

この、defsには

mm.mt.defs
Core.TypeMapEntry(nothing, Tuple{typeof(parsefile),Any}, nothing, svec(), 0x000000000000688e, 0xffffffffffffffff, parsefile(fname) in Main at 
/parsetool.jl:58, false, true, false)

となっていて、

julia> dump(mm.mt.defs)
Core.TypeMapEntry
  next: Nothing nothing
  sig: Tuple{typeof(parsefile),Any} <: Any
  simplesig: Nothing nothing
  guardsigs: empty SimpleVector
  min_world: UInt64 0x000000000000688e
  max_world: UInt64 0xffffffffffffffff
  func: Method
    name: Symbol parsefile
    module: Module Main
    file: Symbol /parsetool.jl
    line: Int32 58
    primary_world: UInt64 0x000000000000688e
    deleted_world: UInt64 0xffffffffffffffff
    sig: Tuple{typeof(parsefile),Any} <: Any
    ambig: Nothing nothing
    resorted: Nothing nothing
    specializations: Core.TypeMapEntry
 以下略

ここから、関数定義を読み取るのは無理かなあ・・・

ちなみにmsのほうは

julia> typeof(mm.ms[1])
Method

こっちは

julia> mm.ms[1].file
Symbol("/Users/shin/Projects/github/parsetools/src/parsetool.jl")

julia> mm.ms[1].line
58

となっていて関数単位の行番号がわかるので、定義をファイルからとってくるのならこちらだろう・・・

julia実行中に関数のソースはいらないから、メモリ上にはないのだろう。
自分でソース読みにいくしかないのなら、ファイルパスから、parsefile()で呼び出す方法しかないかな。

その場合は、今のようなArrayでなくDictにして関数名からcalling treeを取り出せるようにするのか。
その場合、multiple dispatchのような構造がまた別に存在するわけで、すこし整理しないと・・・。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?