Reflection and introspection
تقدم جوليا مجموعة متنوعة من قدرات الانعكاس في وقت التشغيل.
Module bindings
الأسماء العامة لـ Module
متاحة باستخدام names(m::Module)
، والذي سيعيد مصفوفة من عناصر Symbol
تمثل الربط العام. names(m::Module, all = true)
يعيد الرموز لجميع الروابط في m
، بغض النظر عن الحالة العامة.
DataType fields
يمكن استجواب أسماء حقول DataType
باستخدام fieldnames
. على سبيل المثال، بالنظر إلى النوع التالي، فإن fieldnames(Point)
تُرجع مجموعة من Symbol
التي تمثل أسماء الحقول:
julia> struct Point
x::Int
y
end
julia> fieldnames(Point)
(:x, :y)
نوع كل حقل في كائن Point
مخزن في حقل types
من متغير Point
نفسه:
julia> Point.types
svec(Int64, Any)
بينما تم توضيح x
كـ Int
، لم يتم توضيح y
في تعريف النوع، لذلك يتم تعيين y
بشكل افتراضي إلى نوع Any
.
تمثل الأنواع نفسها كهيكل يسمى DataType
:
julia> typeof(Point)
DataType
لاحظ أن fieldnames(DataType)
يعطي أسماء كل حقل من DataType
نفسه، وأحد هذه الحقول هو حقل types
الذي تم ملاحظته في المثال أعلاه.
Subtypes
يمكن سرد الأنواع الفرعية المباشرة لأي DataType
باستخدام subtypes
. على سبيل المثال، يحتوي DataType
المجرد AbstractFloat
على أربعة (ملموسة) أنواع فرعية:
julia> InteractiveUtils.subtypes(AbstractFloat)
5-element Vector{Any}:
BigFloat
Core.BFloat16
Float16
Float32
Float64
سيتم تضمين أي نوع فرعي مجرد في هذه القائمة، ولكن لن يتم تضمين الأنواع الفرعية الأخرى؛ يمكن استخدام التطبيق التكراري لـ subtypes
لفحص شجرة الأنواع الكاملة.
لاحظ أن subtypes
يقع داخل InteractiveUtils
ولكنه يتم تصديره تلقائيًا عند استخدام REPL.
DataType layout
تمثيل DataType
الداخلي مهم للغاية عند التفاعل مع كود C وتتوفر عدة وظائف لفحص هذه التفاصيل. isbitstype(T::DataType)
تعيد true إذا كان T
مخزناً بمحاذاة متوافقة مع C. fieldoffset(T::DataType, i::Integer)
تعيد الإزاحة (بالبايت) للحقل i بالنسبة لبداية النوع.
Function methods
يمكن سرد طرق أي دالة عامة باستخدام methods
. يمكن البحث في جدول إرسال الطرق عن الطرق التي تقبل نوعًا معينًا باستخدام methodswith
.
Expansion and lowering
كما تم مناقشته في قسم Metaprogramming، فإن دالة macroexpand
تعطي التعبير غير المقتبس والمُدخل (Expr
) في شكل ماكرو معين. لاستخدام macroexpand
، يجب عليك quote
كتلة التعبير نفسها (وإلا، سيتم تقييم الماكرو وسيتم تمرير النتيجة بدلاً من ذلك!). على سبيل المثال:
julia> InteractiveUtils.macroexpand(@__MODULE__, :(@edit println("")) )
:(InteractiveUtils.edit(println, (Base.typesof)("")))
تستخدم الدوال Base.Meta.show_sexpr
و dump
لعرض طرق عرض على طراز S-expr وطرق عرض تفصيلية متداخلة بعمق لأي تعبير.
أخيرًا، تعطي دالة Meta.lower
الشكل lowered
لأي تعبير وهي ذات أهمية خاصة لفهم كيفية ارتباط بناء الجملة بالعمليات الأولية مثل التعيينات، والفروع، والاستدعاءات:
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
فحص الشكل المنخفض للدوال يتطلب اختيار الطريقة المحددة للعرض، لأن الدوال العامة قد تحتوي على العديد من الطرق بتوقيعات نوع مختلفة. لهذا الغرض، يتوفر كود خفض محدد للطرق باستخدام code_lowered
، والشكل المستنتج من النوع متاح باستخدام code_typed
. code_warntype
يضيف تمييزًا إلى مخرجات 4d61726b646f776e2e436f64652822222c2022636f64655f74797065642229_40726566
.
أقرب إلى الآلة، يمكن طباعة تمثيل LLVM الوسيط لدالة باستخدام code_llvm
، وأخيرًا، يتوفر كود الآلة المترجم باستخدام code_native
(سيؤدي ذلك إلى تفعيل الترجمة الفورية/توليد الكود لأي دالة لم يتم استدعاؤها سابقًا).
لراحة، هناك نسخ ماكرو من الوظائف المذكورة أعلاه التي تأخذ استدعاءات دالة قياسية وتقوم بتوسيع أنواع المعاملات تلقائيًا:
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
}
لمزيد من المعلومات، راجع @code_lowered
، @code_typed
، @code_warntype
، @code_llvm
، و @code_native
.
Printing of debug information
تأخذ الدوال والماكرو المذكورة أعلاه وسيط الكلمة الرئيسية debuginfo
الذي يتحكم في مستوى معلومات التصحيح المطبوعة.
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
هي: :none
، :source
، و :default
. بشكل افتراضي، لا يتم طباعة معلومات التصحيح، ولكن يمكن تغيير ذلك عن طريق تعيين Base.IRShow.default_debuginfo[] = :source
.