Reflection and introspection
Julia, çeşitli çalışma zamanı yansıma yetenekleri sunar.
Module bindings
Module
için kamuya açık isimler names(m::Module)
kullanılarak elde edilebilir; bu, kamuya açık bağlamaları temsil eden Symbol
elemanlarının bir dizisini döndürecektir. names(m::Module, all = true)
ise m
içindeki tüm bağlamalar için, kamuya açık durumuna bakılmaksızın semboller döndürür.
DataType fields
DataType
alanlarının isimleri fieldnames
kullanılarak sorgulanabilir. Örneğin, aşağıdaki tür için fieldnames(Point)
ifadesi, alan isimlerini temsil eden bir Symbol
demetini döndürür:
julia> struct Point
x::Int
y
end
julia> fieldnames(Point)
(:x, :y)
Point
nesnesindeki her alanın türü, Point
değişkeninin kendisindeki types
alanında saklanır:
julia> Point.types
svec(Int64, Any)
x
bir Int
olarak anotasyonlanmışken, y
tip tanımında anotasyonsuz bırakılmıştır, bu nedenle y
varsayılan olarak Any
tipine sahiptir.
Türler, DataType
adı verilen bir yapı olarak temsil edilir:
julia> typeof(Point)
DataType
fieldnames(DataType)
ifadesinin, DataType
'ın kendisine ait her bir alanın adlarını verdiğini ve bu alanlardan birinin yukarıdaki örnekte gözlemlenen types
alanı olduğunu unutmayın.
Subtypes
Herhangi bir DataType
'ın doğrudan alt türleri subtypes
kullanılarak listelenebilir. Örneğin, soyut DataType
AbstractFloat
dört (somut) alt türe sahiptir:
julia> InteractiveUtils.subtypes(AbstractFloat)
5-element Vector{Any}:
BigFloat
Core.BFloat16
Float16
Float32
Float64
Herhangi bir soyut alt tür de bu listeye dahil edilecektir, ancak bunların daha fazla alt türü dahil edilmeyecektir; subtypes
ifadesinin özyinelemeli uygulanması tam tür ağaç yapısını incelemek için kullanılabilir.
Not edin ki subtypes
InteractiveUtils
içinde yer almaktadır ancak REPL kullanıldığında otomatik olarak dışa aktarılmaktadır.
DataType layout
DataType
'ın içsel temsili, C kodu ile etkileşimde kritik öneme sahiptir ve bu ayrıntıları incelemek için birkaç işlev mevcuttur. isbitstype(T::DataType)
, T
'nin C ile uyumlu hizalamayla saklandığında doğru döner. fieldoffset(T::DataType, i::Integer)
, türün başlangıcına göre alan i için (bayt) ofseti döner.
Function methods
Herhangi bir genel fonksiyonun yöntemleri methods
kullanılarak listelenebilir. Belirli bir türü kabul eden yöntemler için yöntem dağıtım tablosu methodswith
kullanılarak aranabilir.
Expansion and lowering
Metaprogramming bölümünde tartışıldığı gibi, macroexpand
fonksiyonu, belirli bir makro için alıntılanmamış ve interpolasyonlu ifadeyi (Expr
) verir. macroexpand
kullanmak için, ifade bloğunu kendisini quote
edin (aksi takdirde, makro değerlendirilecek ve sonuç yerine geçecektir!). Örneğin:
julia> InteractiveUtils.macroexpand(@__MODULE__, :(@edit println("")) )
:(InteractiveUtils.edit(println, (Base.typesof)("")))
Base.Meta.show_sexpr
ve dump
fonksiyonları, herhangi bir ifadenin S-expr tarzı görünümlerini ve derinlik açısından iç içe geçmiş detay görünümlerini görüntülemek için kullanılır.
Sonunda, Meta.lower
fonksiyonu, herhangi bir ifadenin lowered
formunu verir ve dil yapıların temel işlemlere, örneğin atamalar, dallanmalar ve çağrılar gibi, nasıl eşlendiğini anlamak için özellikle ilgi çekicidir:
julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] ))
:($(Expr(:thunk, CodeInfo(
@ none within `top-level scope`
1 ─ %1 = 1 + 2
│ %2 = sin(0.5)
│ %3 = Base.vect(%1, %2)
└── return %3
))))
Intermediate and compiled representations
Fonksiyonlar için düşürülmüş formu incelemek, belirli bir yöntemi görüntülemek için seçim yapmayı gerektirir, çünkü genel fonksiyonların farklı tür imzalarına sahip birçok yöntemi olabilir. Bu amaçla, yöntem-spesifik kod düşürme code_lowered
kullanılarak mevcuttur ve tür çıkarımlı form code_typed
kullanılarak mevcuttur. code_warntype
, 4d61726b646f776e2e436f64652822222c2022636f64655f74797065642229_40726566
çıktısına vurgulama ekler.
Makineye daha yakın, bir fonksiyonun LLVM ara temsili code_llvm
kullanılarak yazdırılabilir ve nihayetinde derlenmiş makine kodu code_native
kullanılarak erişilebilir (bu, daha önce çağrılmamış herhangi bir fonksiyon için JIT derleme/kod üretimini tetikleyecektir).
Kolaylık sağlamak için, yukarıdaki işlevlerin standart işlev çağrılarını alıp argüman türlerini otomatik olarak genişleten makro sürümleri vardır:
julia> @code_llvm +(1,1)
; @ int.jl:87 within `+`
; Function Attrs: sspstrong uwtable
define i64 @"julia_+_476"(i64 signext %0, i64 signext %1) #0 {
top:
%2 = add i64 %1, %0
ret i64 %2
}
Daha fazla bilgi için @code_lowered
, @code_typed
, @code_warntype
, @code_llvm
, ve @code_native
.
Printing of debug information
Yukarıda bahsedilen fonksiyonlar ve makrolar, yazdırılan hata ayıklama bilgisi seviyesini kontrol eden debuginfo
anahtar kelime argümanını alır.
julia> InteractiveUtils.@code_typed debuginfo=:source +(1,1)
CodeInfo(
@ int.jl:87 within `+`
1 ─ %1 = Base.add_int(x, y)::Int64
└── return %1
) => Int64
debuginfo
için olası değerler: :none
, :source
ve :default
. Varsayılan olarak hata ayıklama bilgisi yazdırılmaz, ancak bu, Base.IRShow.default_debuginfo[] = :source
ayarlanarak değiştirilebilir.