2017-05-09 5 views
2

自分のタイプのデフォルトの文字列メソッドを(私は醜いので)上書きしたいと思います。juliaを使ったコード生成

この関数は

function prettyPrint(value::Any) 
    names::Vector{Symbol} = fieldnames(value) 
    nameCount::Int64 = length(names) 
    stringBuilder::IOBuffer = IOBuffer() 
    print(stringBuilder, string(typeof(value).name) *"(") 
    for (index, name) in enumerate(names) 
    print(stringBuilder, string(name) * "=" * string(getfield(value, name))) 
    if index != nameCount 
     print(stringBuilder, ", ") 
    end 
    end 
    print(stringBuilder, ")") 
    takebuf_string(stringBuilder) 
end 

私はこのコードのビットを使用して、文字列関数を生成しようとしそして

type Foo 
    a::Int64 
    b::String 
    c::Float64 
end 

サンプルタイプを定義できます文字列を生成するために使用される

import Base.string 

for dataType in (:Foo) 
    eval(quote 
     function string(dt::$dataType) 
     prettyPrint(dt) 
     end 
     end) 
end 

foo = Foo(1, "2", 3.0) 
println(string(foo)) 

これは、動作できないことを示す長いエラーメッセージでクラッシュします。

ERROR: LoadError: MethodError: no method matching start(::Symbol) 
Closest candidates are: 
    start(!Matched::SimpleVector) at essentials.jl:170 
    start(!Matched::Base.MethodList) at reflection.jl:258 
    start(!Matched::IntSet) at intset.jl:184 
    ... 
in anonymous at .\<missing>:? 
in include_from_node1(::String) at .\loading.jl:488 
in process_options(::Base.JLOptions) at .\client.jl:265 
in _start() at .\client.jl:321 
while loading ~\codegeneration.jl, in expression starting on line 24 

行24は 'for(:Foo)'行のデータ型です。

私はこの機能をマクロとして欲しがっていますが、私はそれをどうやってやるのか分かりません。

macro PrettyPrint(someType) 
    ? someType is an expression, how do I get to the type 
    ? how do I even know what part of the expression is the type 

end 
@PrettyPrint type Foo 
a::Int64 ... end 
+1

文字列でコード生成を実際に行うべきではありません。実際のメタプログラミングを使用してください。https://docs.julialang.org/en/stable/manual/metaprogramming/ – StefanKarpinski

答えて

6

エラーメッセージは(:Foo) == :Fooです。あなたは反復処理するタプルが必要だと思うので、(:Foo,)が必要です。つまり、evalはこれを行うための好ましい方法ではありません。

あなたは

function Base.show(io::IO, dt::Foo) 
    print(io,prettyprint(dt)) 
end 

を行う場合には、REPLのデフォルトの印刷が変更されます、そして、あなたはreprで文字列バージョンを取得することができます。

+0

要点は、数十を書いてはいけないということですそれらの機能を手でなぜ私はコード生成を使用するのですか? – Nozdrum

+3

@Nozdrum - 'Base.show(io :: IO、dt :: Union {Foo、Bar、Baz})'という組合を使ってください。 –

関連する問題