24-10-2010, 12:41 PM
نسخة دلفي 2010 كانت بها تحسينات على المترجم تعتبر الأكبر منذ نسخة دلفي 2 ودلفي 2009، حيث طالت تلك النسخة دعم كبير للغة دلفي على مستوى المترجم وليس فقط تحسينات لبيئة التطوير والمكونات الموجودة.
اليوم أمضيت بعض الوقت للبدء في تعلم ال Extended RTTI (Real Time Type Information التي أضيفت لدلفي، ورغم أن دلفي ومنذ بدايته كان به دعم جيد نوعاً ما لل RTTI، لكنه هذه الدعم كان محصور ضمن البيانات والطرق المعرفة ضمن جزء ال Published في أي صنف، وأيضا لم يكن على مستوى عالي مثل الموجود في الجافا ولغات الدوت نت في حيث ما يعرف ب Reflection.
لكن مع دلفي 2010 تم زيادة هذا الدعم تحت مسمى Extended RTTI، بحيث أصبح بالإمكان التعامل مع جميع محتويات الصنف وليس ال Published فقط، ومع إضافة دعم ال Attributes للغة دلفي، أصبح بالإمكان الوصول للعديد من المميزات الموجودة في دوت نت وجافا ولكن بدون تضييع مستوى الآمان، حيث لا يمكن إرجاع الكود إلى أصله، وأيضاً يمكن توقيف توليد هذه المعلومات.
يمكن الإطلاع على وحدة rtti.pas التي أضيفت إلى دلفي 2010 وبها TRTTIContext الذي يعتبر قلب التعامل مع ال RTTI، ورغم بساطته لكن يعتبر نقطة البداية في التعامل مع أي صنف من خلال ال RTTI.
سوف أتطرق اليوم لمثال بسيط، حيث سوف أقوم بتعريف صنف جديد TStudClass ومن ثم سوف أقوم بعرض جميع مع يحتويه هذا الصنف من خلال ال RTTI المحسن.
والنتيجة تكون بالشكل التالي:
عندما يتم طباعة مثلا P.ToString أو F.ToString فإنه سوف عرض البيانات الخاصة بالحقل أو الخاصية بالإضافة إلى موقعها في الذاكرة بالنسبة للصنف، لذا فقد قمت بكتابة دالة صغيرة لعرض البيانات بشكل أوضح وهي GetFormattedType، ويمكن رفعها لرؤية الفرق في الناتج.
أيضاً من الملاحظ أنني لم أقم سوف بكتابة Method واحدة ضمن الصنف، لكن تم عرض الكثير منها والتي هي موروثة من الصنف الأب TObject، لذا فبعد قليل من التمحيص ضمن TRTTIMethod وجدت أن ال Parent الخاص يرجع الصنف الأب لل Method التي داخل التكرار، لذا فلو قمنا بفحصها مع النوع الراجع من TRttiContext فهكذا نضمن بأن ال Methods هي تابعة للصنف المراد عرض بياناته فقط، ويصبح جزئية عرضة ال Methods كالتالي:
وتظهر النتجة الآن بشكل صحيح هكذا:
يمكن الحصول أيضاً على معلومات أخرى مثل ال Attributes لكن هذه تحتاج إلى موضوع آخر في الفترة القادمة إن شاء الله.
وإلى لقاء آخر بأذن الله
=======
من مدونتي
اليوم أمضيت بعض الوقت للبدء في تعلم ال Extended RTTI (Real Time Type Information التي أضيفت لدلفي، ورغم أن دلفي ومنذ بدايته كان به دعم جيد نوعاً ما لل RTTI، لكنه هذه الدعم كان محصور ضمن البيانات والطرق المعرفة ضمن جزء ال Published في أي صنف، وأيضا لم يكن على مستوى عالي مثل الموجود في الجافا ولغات الدوت نت في حيث ما يعرف ب Reflection.
لكن مع دلفي 2010 تم زيادة هذا الدعم تحت مسمى Extended RTTI، بحيث أصبح بالإمكان التعامل مع جميع محتويات الصنف وليس ال Published فقط، ومع إضافة دعم ال Attributes للغة دلفي، أصبح بالإمكان الوصول للعديد من المميزات الموجودة في دوت نت وجافا ولكن بدون تضييع مستوى الآمان، حيث لا يمكن إرجاع الكود إلى أصله، وأيضاً يمكن توقيف توليد هذه المعلومات.
يمكن الإطلاع على وحدة rtti.pas التي أضيفت إلى دلفي 2010 وبها TRTTIContext الذي يعتبر قلب التعامل مع ال RTTI، ورغم بساطته لكن يعتبر نقطة البداية في التعامل مع أي صنف من خلال ال RTTI.
سوف أتطرق اليوم لمثال بسيط، حيث سوف أقوم بتعريف صنف جديد TStudClass ومن ثم سوف أقوم بعرض جميع مع يحتويه هذا الصنف من خلال ال RTTI المحسن.
PHP كود :
{*******************************************************}
{ }
{ RTTI Sample with Delphi 2010(+) }
{ }
{ Copyright (C) 2010 Mohammed Nasman }
{ }
{*******************************************************}
program RttiDemo1;
{$APPTYPE CONSOLE}
uses
SysUtils, RTTI;
type
TStudClass = class
private
FStudID: integer;
FStudName: string;
FStudRegDate: TDate;
FStudAddr: string;
public
property StudID :Integer read FStudID write FStudID;
property StudName :string read FStudName write FStudName;
property StudRegDate :TDate read FStudRegDate write FStudRegDate;
property StudAddr :string read FStudAddr write FStudAddr;
procedure PrintStuData;
end;
var
t : TRttiType;
c : TRttiContext;
F : TRTTIField;
M : TRTTIMethod;
P : TRttiProperty;
function GetFormattedType(s:string):string;
var
P : Integer;
begin
P := Pos('@',S);
if P > 0 then
Result := copy(S,1,P-1)
else
Result := S;
end;
{ TStudClass }
procedure TStudClass.PrintStuData;
begin
//
end;
begin
T := c.GetType(TStudClass);
Writeln('============ Listing all fields of Class:',TStudClass.ClassName);
for f in t.GetFields do
Writeln(GetFormattedType(f.ToString));
Writeln;
Writeln('============ Listing all Methods of Class:',TStudClass.ClassName);
for M in t.GetMethods do
if m.Parent = c.GetType(TStudClass) then
Writeln(GetFormattedType(M.ToString));
Writeln;
Writeln('============ Listing all Properties of Class: ',TStudClass.ClassName);
for P in t.GetProperties do
Writeln(GetFormattedType(P.ToString));
Readln;
end.
والنتيجة تكون بالشكل التالي:
عندما يتم طباعة مثلا P.ToString أو F.ToString فإنه سوف عرض البيانات الخاصة بالحقل أو الخاصية بالإضافة إلى موقعها في الذاكرة بالنسبة للصنف، لذا فقد قمت بكتابة دالة صغيرة لعرض البيانات بشكل أوضح وهي GetFormattedType، ويمكن رفعها لرؤية الفرق في الناتج.
أيضاً من الملاحظ أنني لم أقم سوف بكتابة Method واحدة ضمن الصنف، لكن تم عرض الكثير منها والتي هي موروثة من الصنف الأب TObject، لذا فبعد قليل من التمحيص ضمن TRTTIMethod وجدت أن ال Parent الخاص يرجع الصنف الأب لل Method التي داخل التكرار، لذا فلو قمنا بفحصها مع النوع الراجع من TRttiContext فهكذا نضمن بأن ال Methods هي تابعة للصنف المراد عرض بياناته فقط، ويصبح جزئية عرضة ال Methods كالتالي:
PHP كود :
Writeln('============ Listing all Methods of Class:',TStudClass.ClassName);
for M in t.GetMethods do
if m.Parent = c.GetType(TStudClass) then
Writeln(GetFormattedType(M.ToString));
وتظهر النتجة الآن بشكل صحيح هكذا:
يمكن الحصول أيضاً على معلومات أخرى مثل ال Attributes لكن هذه تحتاج إلى موضوع آخر في الفترة القادمة إن شاء الله.
وإلى لقاء آخر بأذن الله
=======
من مدونتي
كود :
http://www.mnasman.com/blog/?p=278