اذهب إلى المحتوى

لوحة المتصدرين

  1. رحيق الزهور

    رحيق الزهور

    الأعضاء


    • نقاط

      1

    • المساهمات

      41


  2. عبدالهادي الديوري

    • نقاط

      1

    • المساهمات

      368


  3. عمر الوريكات

    عمر الوريكات

    الأعضاء


    • نقاط

      1

    • المساهمات

      43


  4. Shahad Mohammad

    Shahad Mohammad

    الأعضاء


    • نقاط

      1

    • المساهمات

      112


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 07/02/22 في كل الموقع

  1. تعرّفنا فيما سبق من دروس هذه السلسلة على أساسيات لغة بايثون، من مُتغيّرات وحلقات تكرار إلى الدوال، وقد حان الوقتُ للدخول إلى أساسيات البرمجة كائنية التوجّه Object Oriented Programming وهي ببساطة طريقة أخرى للبرمجة بحيث تكون أجزاء الشّيفرة مجموعة داخل دوال تُسمّى التوابع methods والدوال تكون داخل صنف معيّن Class. عند إنشاء كائن object من هذا الصنف فإنّنا نستطيع أن نُنفّذ عليه مُختلف العمليات الموجودة داخل التوابع والتي بدورها توجد داخل الصنف. هناك تسميّات عربية أخرى لهذا النّوع من البرمجة، لذا لا تقلق إذا صادَفتَ أحد هذه التّسميات في أماكن أخرى، فكلّها تُشير إلى نفس المعنى: برمجة غرضيّة التوجه برمجة شيئية المنحى برمجة كائنيّة المنحى بنية الصنف Class الصنف ببساطة يحتوي على أجزاء مُختلفة من الشيفرة تماما مثل الدالة، الفرق هنا هو أنّ الصنف يحتوي على دوال كذلك، وهذه الدوال تُسمى التّوابع، ويحتوي كذلك على مُتغيّرات وتنقسم هذه الأخيرة إلى نوعين، مُتغيّر الصنف، والمُتغيّر العادي، الفرق بينهما هو أنّك تستطيع الوصول إلى مُتغيّر الصنف في أي مكان داخل الصنف (سواء داخل التوابع أو خارجها). إنشاء صنف لإنشاء صنف في لغة بايثون كلّ ما عليك فعله هو كتابة كلمة class وبعدها اسم الصنف ثمّ إلحاق نقطتين، بعدها اكتب الشيفرة بإزاحة أربع مسافات: >>> class My_class: ... pass أنشأنا أعلاه صنفًا بسيطا باسم My_class وهو لا يفعل أي شيء يُذكر (كلمة pass تُخبر بايثون بالمرور دون تنفيذ أي شيء). إذا كتبت اسم الصنف على مفسّر بايثون فستجد مُخرجا كالتّالي: >>> My_class <class __main__.My_class at 0x7fd0efc41460> لاحظ بأنّ الكلمة الأولى من المُخرج هي class أي أنّنا أصبحنا نمتلك صنفًا جديدًا، ما يتبع at هو المكان في الذاكرة الذي وُضع فيه الصنف ويتغيّر بين الحين والآخر. إنشاء كائن من صنف بعد أن أنشأنا الصنف سنتمكّن الآن من إنشاء كائن من هذا الصنف، والكائن مُجرّد اسم تماما كالمُتغيّر: my_object = My_class() الآن الكائن my_object هو من صنف My_class. تعريف المتغيرات داخل صنف يُمكننا أن نُعرّف مُتغيّرات في الصنف تماما كما نُعرّف المُتغيّرات بشكل عادي. class My_class: my_variable = 'This is my variable' للوصول إلى المُتغيّر ننشئ أولا كائنا من الصنف وبعدها نكتب اسم الكائن ثمّ نقطة ثمّ اسم المُتغيّر: my_object = My_class() print my_object.my_variable المُخرج: This is my variable يُمكن كذلك الحصول على النّتيجة ذاتها في سطر واحد: print My_class().my_variable إنشاء التوابع التوابع هي دوال خاصّة بالصنف، ويُمكننا إنشاء التابع بنفس الطّريقة التي نُنشئ بها الدالة، الإختلاف هنا هو أنّ جميع التوابع يجب أن تُعرّف مع مُعامل باسم self وذلك للإشارة إلى أنّ الدالة/التابع تابع للصنف، لننشئ تابعا داخل صنف الآن. class My_class: my_variable = 'This is my variable' def my_method(self): print 'This is my method' الآن إذا أنشأنا كائنا فإنّنا سنتمكّن من الوصول إلى التابع، وتذكّر بأنّ التابع تلحقه الأقواس: my_object = My_class() my_object.my_method() المُخرج: This is my method يُمكن كذلك الحصول على النّتيجة ذاتها في سطر واحد: My_class().my_method() كما تُلاحظ فقد نُفّذت الشيفرة الموجودة داخل التّابع my_method ويُمكننا كذلك أن نجعل التّابع يقبل المُعاملات، لكن تذكّر الحفاظ على الكلمة self كمُتغيّر أول. class My_class: my_variable = 'This is my variable' def my_method(self, my_parameter): print 'This is my method ; {} is my parameter'.format(my_parameter) يُمكنك استدعاء التّابع كالتّالي: my_object = My_class() my_object.my_method('Parameter1') my_object.my_method('Parameter2') المُخرج: This is my method ; Parameter1 is my parameter This is my method ; Parameter2 is my parameter في البرنامج السّابق، أنشأنا أولا صنفًا باسم My_class وقُمنا بتعريف مُتغيّر، ثمّ بتعريف تابع باسم my_method يقبل مُعاملين self و my_parameter، بالنّسبة لاستدعاء التّابع، فنحتاج فقط إلى تمرير المُعاملات الموجودة بعد المُعامل selfولا نحتاج إلى تعيين قيمة لهذا المُعامل. مُلاحظة: يُمكنك إعادة تسميّة المُعامل الأول كما تشاء، أي أنّ البرنامج التّالي سيعمل دون مشاكل. class My_class: def my_method(this, my_parameter): print '{} is my parameter'.format(my_parameter) ولكن رغم ذلك فالمُتعارف عليه بين مُبرمجي لغة بايثون هو استعمال self، وفي كثير من اللغات الأخرى تُستعمل this عوضا عن self، أما في برامِجك فمن المُفضّل الإبقاء على هذه التّسميّة المُتعارف عنها، وذلك لتكون شيفراته سهلة القراءة. الوصول إلى متغيرات الصنف داخل التوابع تأمّل الصنف التّالي: class Person: lastname = 'Dyouri' job = 'Writer, Developer' def say_hello(self): name = 'Abdelhadi' print 'Hello, My name is {}'.format(name) البرنامج أعلاه بسيط جدا، أولا نعرّف صنف باسم Person وبعدها نقوم بتعيين قيمتين للمُتغيّرين name و lastname، وبعدها عرّفنا تابعا باسم say_hello يطبع جملة Hello, My name is Abdelhadi. كلّ شيء جيد، لكن ماذا لو أردنا أن نصل إلى المُتغيّرات الأخرى الموجودة خارج التّابع، فلا يُمكننا مثلا أن نقوم بالأمر كالتّالي: class Person: lastname = 'Dyouri' job = 'Writer, Developer' def say_hello(self): name = 'Abdelhadi' print 'Hello, My name is {}'.format(name) print lastname print job ستحصل على الخطأ التّالي: global name 'lastname' is not defined لتفادي هذا الخطأ سنستعمل كلمة self قبل المُتغيّر. class Person: lastname = 'Dyouri' job = 'Writer, Developer' def say_hello(self): name = 'Abdelhadi' print 'Hello, My name is {}'.format(name) print 'My Last name is {} '.format(self.lastname) print 'I am a {}'.format(self.job) استدعاء التّابع: me = Person() me.say_hello() المُخرج: Hello, My name is Abdelhadi My Last name is Dyouri I am a Writer, Developer لاحظ بأنّنا قُمنا بالوصول إلى مُتغيّر lastname عن طريق استدعائه بـ self.lastname وكذا الحال مع المُتغيّر job، وهذه الطّريقة مُشابهة لاستخدام كلمة global الفرق هنا أنّ هذه الأخيرة تُمكن من الوصول إلى المُتغيّر في كامل البرنامج، أمّا كلمة self فتُشير إلى المُتغيّر المُعرّف في الصنف الحاليّة فقط. لتفهم أكثر كيفيّة عمل الكلمة self فقط تخيّل بأنّها تحمل نفس اسم الصنف، مثلا: class Person: lastname = 'Dyouri' job = 'Writer, Developer' def say_hello(self): name = 'Abdelhadi' print 'Hello, My name is {}'.format(name) print 'My Last name is {} '.format(Abd.lastname) print 'I am a {}'.format(Abd.job) لاحظ بأنّنا غيّرنا كلمة self إلى اسم الصنف واستمرّ عمل البرنامج دون مشاكل. وبنفس الطّريقة يُمكنك أن تستدعي تابعا داخل تابع آخر في نفس الصنف: class Person: def say_name(self): print 'Abdelhadi' def say_hello(self): print 'Hello My name is:' self.say_name() المُخرج: Hello My name is: Abdelhadi ما حدث هو أنّ التّابع say_hello قام بطباعة جملة :Hello My name is ثمّ قام باستدعاء التّابع say_name الذي قام بدوره بطباعة الاسم Abdelhadi. لماذا تستعمل البرمجة الكائنية، ومتى يجب علي استخدامها قد تُلاحظ بأنّ ما يُمكنك فعله بالبرمجة الكائنيّة يُمكن القيام به بالدوال والمُتغيّرات فقط. هذا صحيح، وهو أمر واضح، البرمجة الكائنيّة تُستعمل أساسا إذا كان البرنامج الذي تبنيه مُعقّدا مع العديد من الوظائف المُتعلّقة ببعضها (كمكتبة برمجيّة)، مثلا لنقل بأنّك تُطوّر برنامجا مسؤولا عن جلب بيانات من موقع مُعيّن، وبعدها التّعديل عليها، ثمّ إخراج مستند PDF يحتوي على هذه البيانات بشكل يُسهّل قراءتها، هنا ستحتاج إلى صنف لجلب البيانات والتّعديل عليها، وصنف أخرى لتحويل البيانات إلى نصّ مقروء واضح ثمّ إلى ملفّ PDF. إذا نشرت برنامجك مع صديقك وأراد أن يعمل على الجزء الثاني لإضافة وظيفة تُمكن المُستخدم من طباعة المُستند فلا يُعقل أن يضطر للمرور على كل ما يتعلّق بجلب البيانات فقط لأنّه يريد أن يضيف خاصيّة لا علاقة لها بجلب البيانات. استعمال البرمجة الكائنيّة في هذا المشروع سيسمح لك بالتّركيز على الجزء الأول، وسيسمح لصديقك بالتّركيز على تطوير الجزء الثاني. خلاصة الأمر هي أنّك لست مضطرا لاستعمال البرمجة الكائنيّة إلا إذا كان برنامجك طويلا يحتوي على وظائف تتعلّق ببعضها البعض (وظائف من نفس الصنف)، ونسبة استخدام الآخرين لشيفرتك عالية. تمارين التمرين 1 أنشئ صنفًا باسمك، وقم بتعريف مُتغيّرين lastname (الاسم العائلي) و age (العمر)، ثم أنشئ كائنا باسم me (أنا) وقم بطباعة اسمك العائلي وعمرك. التمرين 2 أنشئ صنفًا باسم Car (سيارة) وقم بتعريف مُتغيّرات لصفات السّيارة، مثلا brand لاسم الشّركة، release_date لتاريخ الإعلان عن السّيارة. التمرين 3 أضف توابع إلى الصنف Car التي أنشأتها في التّمرين الثّاني، يُمكن أن تكون التوابع عبارة عن عمليّات تقوم بها السّيارة مثلا move للحركة، stop للتوقّف، slow_down لتخفيض السّرعة، وقم بطباعة جمل تفيد بأنّ العمليّة قد نجحت. المفروض أن يتمكّن الآخرون من إنشاء كائنات خاصّة بهم بحيث تُستخدم بهذه الطّريقة: bmw = Car() bmw.move() bmw.slow_down() bmw.stop() خاتمة تعرّفنا في هذا الدّرس على بعض من أهم أساسيات البرمجة الكائنيّة التوجه في لغة بايثون وهذا الموضوع أطول من أن أشرحه في درس واحد لذلك سيكون الدّرس التّالي تكملة لما تعلّمناه في هذا الدّرس حول تعلم بايثون وسيغطي مفاهيم أخرى حول البرمجة كائنية التوجّه.
    1 نقطة
  2. السلام عليكم مثلا عندما يقول لك هذا النوع يملك 16 bit أي 16 *16 = 256 ’ هل 256-1 تعبر عن عدد الحروف ام ماذا و ما الفرق بين byte ,bit وكيف اتزود من هذا الموضوع ؟
    1 نقطة
  3. البت Bit أو أصغر وحدة للذاكرة مؤلف من خانة وحدة فقط، يمكن أن يمثل قيمتين فقط إما الصفر 0 أو الواحد 1 البايت Byte هو اجتماع 8 بتات، أي أن البايت الواحد يملك 8 خانات كل منها يمكن أن تكون إما 0 أو 1، مثال : 00000000 أو 00110010 بما أن أصغر خانة وهي البت يمكنها تمثيل عددين فقط، ينشئ مفهوم العد الثنائي، وهو العد باستخدام عددين فقط، بينما في حياتنا العادية نستخدم النظام العشري الذي يحوي عشرة أعداد من 0 حتى، لذا في نظام العد الثنائي يمكن حساب العدد الأقصى الذي يمكن تمثيله برفع عدد البتات إلى قوة 2، مثلًا أكبر عدد يمكن للبايت تمثيله هو 8^2 = 256، يمكنك الاطلاع أكثر على ذلك من المقال التالي: في حالة نوع الحقل TEXT كل محرف يُمثّل ببايت واحد، ويتم تحديد طول المحارف المخزنة ضمن خلية ما عبر بايتان في البداية يمثلان عدد المحارف في تلك الخلية، أي العدد الأقصى للمحارف الذي يمكننا تخزينه هو 8^2 = 65,536 محرفًا، كما هو مذكور في الشرح، يمكنك التعرف أكثر على الذواكر وطرق عنونتها والتعامل مع البايتات لهذا الغرض من المقال التالي:
    1 نقطة
  4. لدي 2 div تحت بعض الاول وضعت له position :fixed المشمكلة الDiv الذي تحته يرتفع والى بداية الديف الاول ويختفي لا اعلم ما الحل حيث اني ارين ان يكون الديف الاول ثابت لكن بنفس الوقت لا اريد الديف الثاني يرتفع للاعلى
    1 نقطة
  5. في الحقيقة العنصر الثاني لا يختفي ولكن يرتفع للأعلى ويصبح أسفل العنصر الأول تماما بحيث لا يظهر وللتاكد من هذا الامر يمكنك اعطاء العنصر الاول الخاصية display وقيمتها none وسوف يظهر العنصر الثاني , عند استخدام القيمة fixed نحتاج الى ضبط تموضع العنصر من خلال الخاصيات top , right , left , bottom كالتالي .div1{ background-color: #ff0; position: fixed; top: 0; left: 0; } يمكنك التحكم في القيم فبدلا من 0 يمكنك وضع أي رقم , وهذا الرقم يدل على بعد العنصر عن الشاشة من الاتجاه المحدد , فمثلا لو وضعت قيمة top ب 0 فذلك يعني ان العنصر سوف يبتعد عن اعلى الشاشة بمقدار 0 وهذا يعني أنه سوف يلتصق بأعلى الشاشة , ثم يمكننا اعطاء العنصر الثاني خاصية margin كالتالي .div2{ margin-top: 100px; } وبهذا سو يظهر العنصر الثاني أسفل العنصر الاول يمكنك التحكم في المسافات والقيم حسب التصميم الخاص بك
    1 نقطة
  6. نظرية بت المعلومات (A bit of information theory) البت هو رقم ثنائي ووحدة معلومات أيضًا، فبت واحد يعني احتمالًا من اثنين إما 0 أو 1، أما وجود بتين يعني وجود 4 تشكيلات محتملة: 00 و 01 و 10 و 11. وإذا كان لديك b بت فهذا يعني وجود 2b قيمة محتملة، حيث يتكون البايت مثلًا من 8 بتات أي 256 (28=256) قيمة محتملة. في الاتجاه المقابل، أي إذا علمت عدد القيم المحتملة ولكنك لا تعلم عدد البتات المناسبة، افترض أنك تريد تخزين حرف واحد من حروف الأبجدية التي تتكون من 26 حرفًا فكم بتًا تحتاج؟ لديك 16 قيمة محتملة ب 4 بتات (24 = 16) وبالتالي هذا غير كافٍ لتخزين 26 حرفًا. وتحصل على 32 قيمة محتملة ب 5 بتات وهو كافٍ لتخزين كل الحروف مع قيم فائضة أيضًا. لذلك إذا أردت الحصول على قيمة واحدة من أصل N قيمة محتملة يجب عليك اختيار أصغر قيمة ل b التي تحقق (2b ≥ N)، وبأخد اللوغاريتم الثنائي للطرفين ينتج (b ≥ log2(N)). تعطيك نتيجة رمي قطعة نقود بتًا واحدًا من المعلومات (لأن قطعة النقود تملك وجهين وبالتالي احتمالين فقط). أما نتيجة رمي حجر نرد فتعطيك log2(6)‎ بتًا من المعلومات (لأن حجر النرد له ستة أوجه). حيث إذا كان احتمال النتيجة هو 1 من N فذلك يعني أن النتيجة تحوي log2(N)‎ بتًا من المعلومات عمومًا، وإذا كان احتمال النتيجة هو p مثلًا فبذلك تحوي النتيجة log2(p)‎ من المعلومات. تدعى هذه الكمية من المعلومات بالمعلومات الذاتية (self-information) للنتيجة، وهي تقيس مقدار التفاجؤ الذي تسببه تلك النتيجة، ويدعى هذا المقدار أيضًا surprisal. فإذا كان حصانك مشاركًا في سباق خيل على سبيل المثال ويملك فرصةً واحدة للفوز من أصل 16 فرصة ثم يفوز بالفعل، وبالتالي تعطيك تلك النتيجة 4 بتات من المعلومات (log2(16)=4)، أما إذا فاز حصان ما بنسبة 75% من المرات، فيتضمن ذلك الفوز الأخير 0.42 بتًا من المعلومات فقط. حيث تحمل النتائج غير المتوقعة معلومات أكثر، أما عند تأكّدك من حدوث شيء ما فلن يعطيك حدوثه بالفعل إلّا كمية قليلة من المعلومات. ينبغي عليك أن تكون على معرفة بالتحويل بين عدد البتات الذي نرمز له ب b وعدد القيم N التي تشفّرها (encode) تلك البتات بحيث N=2b. الذاكرة والتخزين (Memory and storage) تُحفَظ معظم بيانات عملية ما في الذاكرة الرئيسية (main memory) ريثما تنفّذ تلك العملية، حيث أن الذاكرة الرئيسية هي نوع من الذواكر العشوائية (random access memory وتختصر إلى RAM). الذاكرة الرئيسية هي ذاكرة متطايرة (volatile) على معظم الحواسيب، والتي تعني أن محتوياتها تُفقد عند إغلاق الحاسوب. يملك الحاسوب المكتبي النموذجي ذاكرة تتراوح بين 4 و 8 جيبي بايت وربما أكثر بكثير من ذلك، حيث GiB تشير إلى جيبي بايت وهي 230 بايتًا. إذا قرأت وكتبت عملية ما ملفات فإن هذه الملفات تُخزّن على القرص الصلب (hard disk drive ويختصر إلى HDD) أو على (solid state drive ويختصر إلى SSD). وسائط التخزين هذه غير متطايرة (non-volatile)، لذلك تُستخدم للتخزين طويل الأمد. يحتوي الحاسوب المكتبي حاليًا HDD بسعة تتراوح بين 500 جيجا بايت و 2 تيرا بايت، حيث GB هي جيجا بايت وتقابل 109 بايتًا بينما تشير TB إلى تيرا بايت وتساوي 1012 بايتًا. لابد أنك لاحظت استخدام وحدة النظام الثنائي الجيبي بايت، أي التي تعد الكيلوبايت مثلًا مساويًا 1024 بايتًا أو 210 حيث أساسها العدد 2، لقياس حجم الذاكرة الرئيسية واستخدام وحدتي النظام العشري الجيجا بايت و التيرا بايت، أي التي تعد الكيلو بايت مثلًا مساويًا 1000 بايتًا حيث أساسها العدد 10، لقياس حجم HDD. يقاس حجم الذاكرة بالوحدات الثنائية وحجم القرص الصلب بالوحدات العشرية وذلك لأسباب تاريخية وتقنية، ولكن تُستخدم الجيجا بايت واختصارها GB استخدامًا مبهمًا لذلك يجب أن تنتبه لذلك. يُستخدم مصطلح ذاكرة (memory) أحيانًا للدلالة على HDDs و SSDs و RAM، ولكن خصائص هذه الأجهزة الثلاث مختلفة جدًا. يشار إلى HDDs و SSDs بتخزين دائم (storage). أحياز العنونة (Address spaces) يُحدد كل بايت في الذاكرة الرئيسية بعدد صحيح يدعى عنوانًا حقيقيًا (physical address)، حيث تدعى مجموعة العناوين الحقيقية الصالحة بحيز العنونة الحقيقية (physical address space) وتتراوح تلك العناوين بين 0 و N - 1 حيث N هو حجم الذاكرة الرئيسية. أعلى قيمة عنوان صالحة في نظام ب 1 جيبي بايت ذاكرة حقيقية هو 230- 1 ، أي 1,073,741,823 في نظام العد العشري و 0x3f fffff في نظام العد الست عشري حيث تحدد السابقة 0x أنه عدد ست عشري. توفر معظم أنظمة التشغيل ذاكرةً وهميةً (virtual memory) أيضًا، والتي تعني أن البرامج لا تتعامل أبدًا مع عناوين حقيقية (physical addresses) وليست ملزمة بمعرفة كمية الذاكرة الحقيقية المتوفرة. وبدلًا من ذلك تتعامل البرامج مع الذاكرة الوهمية والتي تتراوح قيمها بين 0 و M - 1، حيث M هو عدد العناوين الوهمية الصالحة. ويحدد نظام التشغيل والعتاد الذي يعمل عليه حجم حيّز العنونة الوهمية. لا بد أنك سمعت الناس يتحدثون عن نظامي التشغيل 32 بت و 64 بت، حيث يحدد هذان المصطلحان حجم المسجلات والذي هو حجم العنوان الوهمي أيضًا. فيكون العنوان الوهمي 32 بتًا على نظام 32 بت والذي يعني أن حيز العنونة الوهمية يتراوح بين 0 و 0xffff ffff، أي حجم العنونة الوهمية هو 232 بايتًا أو 4 جيبي بايت. أما على نظام 64 بت فحجم حيز العنونة الوهمية هو 264 بايتًا أو 24.10246 بايتًا، أي 16 اكسبي بايت (exbibytes) والذي هو أكبر من حجم الذاكرة الحقيقية الحالية بمليار مرة تقريبًا. يولّد البرنامج عناوينًا وهمية بكل عملية قراءة أو كتابة في الذاكرة، ويترجمها العتاد إلى عناوين حقيقية بمساعدة نظام التشغيل قبل الوصول إلى الذاكرة الرئيسية، وتقوم هذه الترجمة على أساس per-process أي تعامَل كل عملية باستقلالية عن العمليات الأخرى، حيث حتى لو ولّدت عمليتان نفس العنوان الوهمي فسترتبطان بمواقع مختلفة من الذاكرة الحقيقية. إذًا الذاكرة الوهمية هي إحدى طرق نظام التشغيل لعزل العمليات عن بعضها البعض، حيث لا تستطيع عملية ما الوصول إلى بيانات عملية أخرى، فلا وجود لعنوان وهمي يستطيع توليد ارتباطات (maps) بذاكرة حقيقية مخصصة لعملية أخرى. أجزاء الذاكرة (Memory segments) تُنظّم بيانات العملية المُشغّلة ضمن خمسة أجزاء: جزء الشيفرة (code segment): ويتضمن نص البرنامج (program text) وهو تعليمات لغة الآلة التي تبني البرنامج. الجزء الساكن (static segment): يتضمن القيم غير القابلة للتغيير، قيم السلاسل النصية (string literals) مثلًا، حيث إذا احتوى برنامجك على سلسلة مثلًا "Hello, World" فستُخزَّن هذه الحروف في الجزء الساكن من الذاكرة. الجزء العام (global segment): يتضمن المتغيرات العامة (global variables) والمتغيرات المحلية (local variables) التي يُصرَّح عنها كساكنة static. جزء الكومة (heap segment): يتضمن قطع الذاكرة المخصصة في زمن التشغيل وذلك باستدعاء دالة مكتبة في لغة C هي malloc في أغلب الأحيان. جزء المكدس (stack segment): يتضمن استدعاء المكدس وهو سلسلة من إطارات المكدس (stack frames). يُخصَّص إطار المكدس ليتضمن المعاملات والمتغيرات المحلية الخاصة بالدالة في كل مرة تّستدعى فيها الدالة، ويزال إطار المكدس ذاك التابع لتلك الدالة من المكدس عندما تنتهي الدالة من عملها. يتشارك المصرِّف مع نظام التشغيل في تحديد ترتيب الأجزاء السابقة، حيث تختلف تفاصيل ذلك الترتيب من نظام تشغيل لآخر ولكن الترتيب الشائع هو: يوجد جزء نص البرنامج أو جزء الشيفرة قرب قاع (bottom) الذاكرة أي عند العناوين القريبة من القيمة 0. يتواجد الجزء الساكن غالبًا فوق جزء الشيفرة عند عناوين أعلى من عناوين جزء الشيفرة. ويتواجد الجزء العام فوق الجزء الساكن غالبًا. ويتواجد جزء الكومة فوق الجزء العام وإذا احتاج للتوسع أكثر فسيتوسع إلى عناوين أكبر. ويكون جزء المكدس قرب قمة الذاكرة (top of memory) أي قرب العناوين الأعلى في حيز العنونة الوهمية، وإذا احتاج المكدس للتوسع فسيتوسع للأسفل باتجاه عناوين أصغر. لتعرف ترتيب هذه الأجزاء على نظامك، نفّد البرنامج التالي: #include <stdio.h> #include <stdlib.h> int global; int main() { int local = 5; void *p = malloc(128); char *s = "Hello, World"; printf("Address of main is %p\n", main); printf("Address of global is %p\n", &global); printf("Address of local is %p\n", &local); printf("p points to %p\n", p); printf("s points to %p\n", s); } main هو اسم دالة ولكن عند استخدامها كمتغير فهي تشير إلى عنوان أول تعليمة لغة آلة في الدالة main والتي من المتوقع أن تكون في جزء الشيفرة (text segment). أما global فهو متغير عام (global variable) وبالتالي يُتوقع تواجده في الجزء العام (global segment)، و local هو متغير محلي أي يتواجد في جزء المكدس. ترمز s إلى سلسلة نصية (string literal) وهي السلسلة التي تكون جزءًا من البرنامج، على عكس السلسلة التي تُقرَأ من ملف أو التي يدخلها المستخدم. ومن المتوقع أن يكون موقع هذه السلسلة هو الجزء الساكن (static segment)، في حين يكون المؤشر s الذي يشير إلى تلك السلسلة متغيرًا محليًا. أما p فيتضمن العنوان الذي يعيده تنفيذ الدالة malloc حيث أنها تخصص حيزًا في الكومة، وترمز malloc إلى memory allocate أي تخصيص حيز في الذاكرة. يخبر التنسيق التسلسلي format sequence %pالدالة printf بأن تنسق كل عنوان كمؤشر (pointer) فتكون النتيجة عبارة عن عدد ست عشري (hexadecimal). عند تنفيذ البرنامج السابق سيكون الخرج كما يلي: Address of main is 0x 40057d Address of global is 0x 60104c Address of local is 0x7ffe6085443c p points to 0x 16c3010 s points to 0x 4006a4 عنوان main هو الأقل كما هو متوقع، ثم يتبعه موقع سلسلة نصية (string literal)، ثم موقع global، وبعده العنوان الذي يشير إليه المؤشر p، ثم عنوان local أخيرًا وهو الأكبر. يتكون عنوان local وهو العنوان الأكبر من 12 رقمًا ست عشريًا حيث يقابل كل رقم ست عشري 4 بتات وبالتالي يتكون هذا العنوان من 48 بتًا، ويدل ذلك أن القسم المُستخدم من حيز العنونة الوهمية هو 248 بايتًا لأن حجم حيز العنونة الوهمية يكون مساويًا 2x بايتًا (تمثل x حجم العنوان الوهمي)، وأكبر عنوان مستخدم في هذا المثال هو 48 بتًا. جرب تنفيذ البرنامج السابق على حاسوبك وشاهد النتائج، أضف استدعاءً آخر للدالة malloc وتحقق فيما إذا أصبح عنوان كومة نظامك أكبر، وأضف أيضًا دالة تطبع عنوان متغير محلي وتحقق إذا أصبح عنوان المكدس يتوسع للأسفل. يوضح المخطط التالي عملية ترجمة العناوين: المتغيرات المحلية الساكنة (Static local variables) تدعى المتغيرات المحلية في المكدس بمتغيرات تلقائية (automatic) لأنها تُخصص تلقائيًا عند استدعاء الدالة وتحرر مواقعها تلقائيًا أيضًا عندما ينتهي تنفيذ الدالة. أما في لغة البرمجة C فيوجد نوع آخر من المتغيرات المحلية، تدعى ساكنة (static)، تخصص مواقعها في الجزء العام (global segment) وتُهيّأ عند بدء تنفيذ البرنامج وتحافظ على قيمتها من استدعاءٍ لآخر للدالة. تتتبّع الدالة التالية عدد مرات استدعائها على سبيل المثال: int times_called() { static int counter = 0; counter++; return counter; } تحدد الكلمة المفتاحية static أن المتغير counter هو متغير محلي ساكن، حيث أن تهيئة المتغير المحلي الساكن تحدث مرة واحدة فقط عند بدء تنفيذ البرنامج، ويخصص موقع المتغير counter في الجزء العام مع المتغيرات العامة وليس في جزء المكدس. ترجمة العناوين (Address translation) كيف يُترجم العنوان الوهمي (VA) إلى عنوان حقيقي (PA)؟ العملية الأساسية لتحقيق ذلك بسيطة، ولكن يمكن أن يكون التنفيذ البسيط أيضًا بطيئًا ويأخذ مساحة أكثر، لذلك يكون التنفيذ الحقيقي أعقد. توفر معظم العمليات وحدة إدارة الذاكرة (memory management unit وتختصر إلى MMU) التي تتموضع بين المعالج CPU والذاكرة الرئيسية وتطبّق ترجمة سريعة بين العناوين الوهمية والعناوين الحقيقية كما يلي: يولّد المعالج CPU عنوانًا وهميًا (VA) عندما يقرأ أو يكتب البرنامج متغيرًا . تقسّم MMU العنوان الوهمي إلى قسمين هما رقم الصفحة والإزاحة (page number و offset). الصفحة (page) تعني قطعة ذاكرة ويعتمد حجم هذه الصفحة على نظام التشغيل والعتاد ولكن حجوم الصفحات الشائعة هي بين 1 و 4 كيبي بايت. تبحث MMU عن رقم الصفحة في مخزَن الترجمة الجانبي المؤقت (translation lookaside buffer)، يُختصر إلى TLB، لتحصل MMU على رقم الصفحة الحقيقي المقابل ثم تدمج رقم الصفحة الحقيقي مع الإزاحة لينتج العنوان الحقيقي PA. يمرَّر العنوان الحقيقي إلى الذاكرة الرئيسية التي تقرأ أو تكتب الموقع المطلوب. يتضمن TLB نسخ بيانات مخبئية من جدول الصفحات (page table) والتي تُخزن في ذاكرة النواة، ويحتوي جدول الصفحات ربطًا بين أرقام الصفحات الوهمية و أرقام الصفحات الحقيقية. وبما أن لكل عملية جدول صفحاتها الخاص لذلك يجب على TLB أن يتأكد من أنه يستخدم مدخلات جدول صفحات العملية التي تنفّذ فقط. لفهم كيف تتم عملية الترجمة افترض أن العنوان الوهمي VA هو 32 بتًا والذاكرة الحقيقية 1 جيبي بايت مقسّمة إلى صفحات وكل صفحة ب 1 كيبي بايت: بما أن 1 جيبي بايت هي 230 بايتًا و 1 كيبي بايت هي 210 بايت لذلك يوجد 220 صفحةً حقيقية تدعى أحيانًا إطارات (frames). حجم حيز العنونة الوهمية هو 232 بايتًا وحجم الصفحة هو 210 بايتًا لذلك يوجد 222 صفحة وهمية. يحدد حجم الصفحة حجمَ الإزاحة وفي هذا المثال حجم الصفحة هو 210 بايتًا لذلك يتطلب 10 بتات لتحديد بايت من الصفحة. وإذا كان العنوان الوهمي 32 بتًا والإزاحة 10 بت فتشكّل ال22 بتًا المتبقية رقم الصفحة الوهمية. وبما أنه يوجد 220 صفحة حقيقية فكل رقم صفحة حقيقية هو 20 بتًا وأضف عليها إزاحة ب 10 بت فتكون العناوين الحقيقية الناتجة ب 30 بتًا. يبدو كل شيء معقولًا حتى الآن، ولكن التنفيذ الأبسط لجدول الصفحات هو مصفوفة بمدخلة واحدة لكل صفحة وهمية، وتتضمن كل مدخلة رقم الصفحة الفعلية وهي 20 بتًا في هذا المثال، بالإضافة إلى بعض المعلومات الإضافية لكل إطار أو صفحة حقيقية، وبالتالي من 3 إلى 4 بايتات لكل مدخلة من الجدول ولكن مع 222 صفحة وهمية يكون حجم جدول الصفحات 224 بايتًا أو 16 ميبي بايت. تحتاج كل عمليةٍ إلى جدول صفحات خاص بها لذلك إذا تضمن النظام 256 عملية مشغّلة فهو يحتاج 232 بايتًا أو 4 جيبي بايت لتخزين جداول الصفحات فقط! وذلك مع عناوين وهمية ب 32 بتًا وبالتالي مع عناوين وهمية ب 48 و 64 بتًا سيكون حجم تخزين جداول الصفحات كبيرًا جدًا. لا نحتاج لتلك المساحة كلها لتخزين جدول الصفحات لحسن الحظ، لأن معظم العمليات لا تستخدم إلا جزءًا صغيرًا من حيز العنونة الوهمية الخاص بها، وإذا لم تستخدم العملية صفحةً وهمية فلا داعي لإنشاء مدخلة لها في جدول الصفحات. يمكن القول بأن جداول الصفحات قليلة الكثافة (أو مخوَّخَة sparse) والتي تطبيقها باستخدام التنفيذات البسيطة، مثل مصفوفة مدخلات جدول الصفحات، هو أمر سيء. ولكن يمكن تنفيذ المصفوفات قليلة الكثافة أو المخوَّخَة (sparse arrays) بطرق أخرى أفضل لحسن الحظ. فأحد الخيارات هو جدول صفحات متعدد المستويات (multilevel page table) الذي تستخدمه العديد من أنظمة التشغيل، Linux مثلًا. الخيار الآخر هو الجدول الترابطي (associative table) الذي تتضمن كل مدخلة من مدخلاته رقم الصفحة الحقيقية والوهمية. يمكن أن يكون البحث في الجدول الترابطي بطيئًا برمجيًا، أما عتاديًا يكون البحث في كامل الجدول على التوازي (parallel)، لذلك تستخدم المصفوفات المترابطة (associative arrays) غالبًا في تمثيل مدخلات جدول الصفحات في TLB. يمكنك قراءة المزيد عن ذلك من خلال: https://en.wikipedia.org/wiki/Page_table كما ذُكر سابقًا أن نظام التشغيل قادر على مقاطعة أية عملية مُشغّلة ويحفظ حالتها ثم يشغّل عملية أخرى. تدعى هذه الآلية بتحويل السياق (context switch). وبما أن كل عملية تملك جدول الصفحات الخاص بها فيجب على نظام التشغيل بالتعاون مع MMU أن يتأكد من أن كل عملية تحدث على جدول الصفحات الصحيح. وفي الآلات القديمة كان ينبغي أن تُستبدل معلومات جدول الصفحات الموجودة في MMU خلال كل عملية تحويل سياق، وبذلك كانت التكلفة باهظة. أما في الأنظمة الجديدة فإن كل مدخلة في جدول الصفحات ضمن MMU تتضمن معرّف عملية (process ID) لذلك يمكن أن تكون جداول صفحات عمليات متعددة موجودة في نفس الوقت في MMU. ترجمة -وبتصرّف- للفصل Virtual memory من كتاب Think OS A Brief Introduction to Operating Systems
    1 نقطة
  7. من الوهلة الأولى يبدو لنا إطار العمل هذا وكأنّه بسيط ويسهل التعامل معه، وبالطبع هو كذلك والبدء باستخدامه ليس بالأمر الصعب فتوثيق هذا الإطار مكتوب بشكل ممتاز ويحتوي على الكثير من الشيفرات البرمجية المتعلقة باللغات HTML، CSS وجافاسكربت. وصحيح أنّ المغالطات المهمة مذكورة في ذلك التوثيق، ولكن بعض الأخطاء والمشاكل قد تكون غير ظاهرة أو قد تكون موجودة في حالات استخدام غامضة. ولأنّ إطار عمل Bootstrap يبدو بسيطًا وسهل الاستعمال فإنّ هذا الإطار انتشر كالنار في الهشيم وبدأ الكثير من المطورين باستخدامه مما أدّى إلى حدوث الكثير من الأخطاء وظهور بعض المشاكل. لذلك سوف نقوم في هذا المقال بسرد 10 أخطاء شائعة يقوم بها مستخدمو هذا الإطار. الخطأ 1: إساءة فهم هذا الإطار في المقام الأولهناك بعض المفاهيم الخاطئة موجودة في عقول المطورين حول هذا الإطار، وقد يكون ذلك بسبب أنّ هذه المفاهيم غير موجودة بشكل صريح وواضح في الموقع الخاص بإطار العمل أو بسبب أنّ المطورين لا يأخذون الوقت الكافي لقراءة توثيق هذا الإطار. وقد يقوم المطورون بالقيام بالعديد من الأمور بشكل خاطئ وبعدها يلقون اللوم على إطار العمل نفسه، لذلك دعونا نوضح بعض الحقائق المهمة. إنّ إطار العمل Bootstrap يُعتبر إطار عمل شامل ومتكامل ولكنه ليس ضخمًا أو هائل الحجم. ويأتي هذا الإطار بقوالب أساسية تحتوي على العديد من مكونات واجهة المستخدم مثل الجداول (tables) والنماذج (forms) والأزرار (buttons) والقوائم المنسدلة (dropdowns) والكثير الكثير. ويمكنك استخدام هذه المكونات لإنشاء واجهة تعمل على العديد من المتصفحات والأجهزة والأبعاد بأفضل شكل ممكن. وصحيح أنّ إطار العمل لن يقوم بكل شيء ولكنه يوّفر مجموعة من الخيارات لتختار منها مما يساعد المطورين في التركيز على التطوير أكثر من التصميم ويساعدهم في الحصول على موقع جميل بوقت قليل. وهذا الإطار مرن بحيث يمكنك التعديل عليه من إضافة وحذف حتى يتناسب مع احتياجاتك. وصحيح أنّه كان هناك بعض القيود في الإصدارات الأولية لهذا الإطار إلا أنّه الآن أصبح أفضل ويمكن تطويعه بكل سهولة. الخطأ 2: الإعتقاد بأنك لن تحتاج إلى معرفة CSS لاستخدام هذا الإطار وبأنك لن تحتاج إلى مصمم.إذا كنت تعتقد أنّك لن تحتاج إلى معرفة CSS حتى تستخدم هذا الإطار فأنت مخطئ لا محال، فأي مطور ويب يحتاج إلى معرفة CSS وHTML5. وصحيح أنّه يوفر عليك عناء التعامل مع بعض الأمور المزعجة الخاصة بلغة CSS (مثل الـvendor prefixie) ويعطيك العديد من التنسيقات الإفتراضية إلّا أنّه يجب عليك أن تفهم لغة CSS. وقد لا تحتاج إلى معرفة كيف تعمل استعلامات الوسائط (media queries) ولكنك بالطبع سوف تحتاج إلى معرفة كيف يعمل التصميم المتجاوب بشكل عام، فأُطر العمل ليست مصممة لتعليمك CSS ولكنها قد تساعد في ذلك. قد تعتقد أنّك لن تحتاج إلى مصمم إذا ما استخدمت Bootstrap، ولكن مع ذلك يجب عليك التعامل مع أحد المصممين إذا كان ذلك ممكنًا. فإحدى أهم المشاكل الموجودة حاليًا هو أنّ الكثير من المواقع أصبحت تشبه بعضها بسبب استخدام إطار عمل Bootstrap. وقد لا يكون هذا صحيحًا فهناك الملايين من المواقع المصممة باستخدام Bootstrap، فيمكنك مثلًا الدخول إلى موقع Bootstrap Expo فهو عبارة عن معرض أعمال يحتوي على العديد من المواقع التي بُنيت باستخدام هذا الإطار. ألقِ نظرة عليها فقد تلهمك لبناء شيء خاص بك. الخطأ 3: تغيير ملف CSS الإفتراضي لهذا الإطاردعنا نجعل ذلك بسيطًا ومباشرًا: لا تقم أبدًا بتعديل ملف bootstrap.css. إذا قمت بالتعديل على ذلك الملف فالأمور سوف تصبح معقدة وسوف تقوم بتدمير التصميم عندما تقوم بتحديث ملفات Bootstrap عند صدور إصدار جديد من هذا الإطار. يمكنك استبدال التنسيقات الإفتراضية لهذا الإطار بالتنسيقات التي تريدها (مثل colors، margins، paddings) وليس هناك حاجة إلى التعديل على ملف bootstrap.css إطلاقًا. لا تعرف كيفية استخدام LESS أو SASS؟ لا مشكلة في ذلك، كل ما عليك فعله هو إنشاء ملف CSS وتضع فيه التنسيقات التي تريد استبدالها من ملف bootstrap.css الرئيسي. وكما ذكرنا سابقًا فمعرفة CSS أمر في غاية الأهمية حتى لو كنت تعتقد غير ذلك. فيمكنك إنشاء محددات أو فئات (classes) CSS جديدة وتضعها في ملف HTML خاصتك حتى تقوم باستبدال التنسيقات الافتراضية للـBootstrap (لا تنسَ أن تضع ملف CSS الخاص بك بعد ملفات CSS الافتراضية الخاصة بالـBootstrap حتى يعمل كل شيء بشكل صحيح). ما زلت تريد معرفة المزيد والغوص في هذا الإطار بشكل أعمق؟ إذاً أقترح عليك وبشدة أن تنظر إلى الكود المصدري لملفات LESS فبالتأكيد سوف يتضح لك كل شيء بشكل أفضل إذا ما قمت بذلك. الخطأ 4: استخدام كل شيء يوفره إطار Bootstrapقلنا سابقًا بأنّ هذا الإطار شامل ومتكامل ويوفر العديد من مكونات واجهة المستخدم والعديد من قوالب HTML وCSS وإضافات جافاسكربت كذلك. ولكن يجب عليك ألّا تستخدم كل ما يقدمه هذا الإطار إذا كنت لن تحتاجه في المشروع الذي تعمل عليه. وهذا الأمر صحيح خصوصًا مع إضافات الجافاسكربت، فيجب عليك أن تختار فقط الإضافات التي سوف تحتاجها ولا يجب عليك أن تستخدم كل شيء لأنه يبدو جميلًا ورائعًا، فقد يؤدي ذلك إلى إثقال موقعك وجعله بطيئًا. لذلك يجب عليك في البداية أن لا تقوم بإدراج ملف bootstrap.js وأن تقوم بإنشاء موقعك باستخدام HTML وCSS فقط وبعد ذلك تقوم بإضافة المكونات التي تحتاجها واحدة تلو الأخرى. الخطأ 5: إساءة استخدام النوافذ المنبثقة (modals)يوفّر Bootstrap مجموعة من الخيارات المرنة بأقل متطلبات تشغيل ممكنة، كما أنها تأتي بقيم افتراضية مناسبة. وصحيح أنّه من السهل استخدامها ولكن هناك بعض الأمور التي يجب وضعها في الحسبان لتجنب اساءة استخدامها. 1- إظهار أكثر من نافذة منبثقة في نفس الوقتإنّ Bootstrap لا يدعم النوافذ المتداخلة، أي أنّه يمكن إظهار نافذة واحدة فقط في نفس الوقت وإذا أردت إظهار أكثر من نافذة في نفس الوقت فيجب عليك كتابة بعض الأكواد للقيام بذلك. 2- ظهور النافذة خلف الخلفيةإذا كان حاوي النافذة أو العنصر الأب لها متموضعًا بشكل ثابت أو نسبي (fixed or relative position) فإنّ النافذة لن تظهر بشكل مناسب، ولذلك يجب عليك التأكد بأنّ حاوي النافذة لا يحتوي على خاصية position خاصة. فمن أفضل الممارسات وضع HTML الخاص بالنافذة قبل وسم الاغلاق <body/> مباشرة، أو حتى وضعها بعد وسم <body> مباشرة، فهذه هي أفضل طريقة لمنع العناصر الأخرى من التأثير عليها. 3- النوافذ المنبثقة في الأجهزة المحمولةهناك بعض التحذيرات للمطورين بأنّ يكونوا حذرين عند استخدام النوافذ في الأجهزة المحمولة التي تحتوي على لوحة مفاتيح افتراضية. وهذا صحيح بشكل خاص في الأجهزة التي تعمل بنظام iOS فهناك خطأ برمجي يمنع العناصر الثابتة من تغيير مكانها عند استدعاء لوحة المفاتيح الافتراضية، وهذا الأمر لا يمكن لإطار Bootstrap التعامل معه، لذلك فإنّه يجب على المطور التعامل مع هذه المواقف بأفضل شكل ممكن. الخطأ 6: مشكلة زر متصفح الملفاتإنّ إطار عمل Bootstrap لا يوفّر مكون محدد للحصول على زر رفع للمفات (file upload). ولكن يمكنك استخدام الشيفرات البرمجية التالية للحصول على ذلك: <span class="btn btn-default btn-file"> Browse <input type="file"> </span>.btn-file { position: relative; overflow: hidden; } .btn-file input[type=file] { position: absolute; top: 0; right: 0; min-width: 100%; min-height: 100%; font-size: 100px; text-align: right; filter: alpha(opacity=0); opacity: 0; outline: none; background: white; cursor: inherit; display: block; }هناك العديد من الأمثلة لكيفية الحصول على شيء مشابه، فالشيفرة البرمجية السابقة مأخوذة من هذه المقالة وهي توفر شرحًا وافيًا لهذه المشكلة. الخطأ 7: تعقيد الأمور باستخدام الجافاسكربت وإهمال الصفة "data-"إنّ المصممين أو المبتدئين في استخدام الجافاسكربت يمكنهم بكل سهولة إنشاء صفحات ويب باستخدام HTML، CSS وBootstrap. ولكنهم إن لم يكونوا جيدين في البرمجة فقد يقعون في فخ إساءة استخدام الجافاسكربت أو حتى تعقيد الأمور. ومن المهم ذكر أنّه يمكن استخدام إضافات الجافاسكربت باستخدام واجهة تطبيقات برمجية (API) يوفرها إطار عمل Bootstrap ومن دون الحاجة إلى كتابة سطر جافاسكربت واحد. فيمكننا على سبيل المثال أن نقوم بتفعيل نافذة منبثقة (modal dialog) من دون كتابة سطر جافاسكربت واحد وذلك عن طريق استخدام: data-toggle="modal" على عنصر مثل زر (button) أو رابط (anchor) وتمرير قيم إضافية باستخدام الصفات data-. ففي الشيفرة البرمجية الموجودة في الأسفل قمنا بتحديد عنصر له id "#myModal"، وقمنا باستخدام الخيار data-backdrop لمنع النافذة من الاختفاء إذا ما قام المستخدم بالنقر خارج النافذة، وباستخدام الخيار data-keyboard قمنا بتعطيل زر الخروج (escape) الموجود في لوحة المفاتيح الذي يقوم بإغلاق النافذة عند الضغط عليه. وكل ذلك تم باستخدام سطر HTML واحد فقط: <button type="button" data-toggle="modal" data-target="#myModal" data-backdrop="static" data-keyboard="false">Launch my modal</button>الخطأ 8: إهمال الأدوات التي تسهل عملية التطوير باستخدام Bootstrapالأخطاء تحدث وكل مطور يقع في الأخطاء بين الحين والآخر. وهذا أمر لا بد منه ولكن ما يهم هو كيفية التعامل مع الخطأ أو المشكلة. وقد لاحظ فريق تطوير هذا الإطار بأنّ بعض الأخطاء تحصل بشكل متكرر أكثر من الأخرى ولذلك حاولوا أتمتة عملية التطوير، لذلك قاموا بتطوير أداة Bootlint وهي أداة تقوم بتفحص الصفحات التي تستخدم Bootstrap للبحث عن الأخطاء الشائعة. ويمكنك استخدام الأداة في المتصفح مباشرة أو عن طريق سطر الأوامر في Node.js. لذلك يجب على كل مطور أن يستخدم هذه الأداة لتفادي الوقوع في الكثير من المشاكل الشائعة والتي تقوم بإبطاء عملية التطوير. وفي حالة أنك أردت أن تساهم في تطوير مشروع Bootstrap فأعتقد أنه من الجيد لك إلقاء نظرة على Rorschach. بحيث يقوم Rorschach بعمل بعض الفحوصات على طلبات السحب (pull requests) الجديدة وإذا فشل الفحص فإنه يترك تعليق مُفيد لتوضيح الخطأ وكيفية إصلاحه وبعدها يقوم بإغلاق الطلب. الخطأ 9: مشاكل التوافق في متصفح IE8 والمتصفحات الأقدمإنّ Bootstrap مصمم ليعمل بأفضل شكل في الاصدارات الحديثة من متصفحات سطح المكتب والهواتف، وقد تُظهر المتصفحات القديمة المكونات والعناصر بتنسيقات مختلفة ولكن كل شيء يجب أن يعمل بأفضل شكل. ويتضمن الدعم متصفحات IE8 وIE9 مع ملاحظة انّ بعض خصائص CSS3 وعناصر HTML5 ليست مدعومة بشكل كامل في هذه المتصفحات. وللحصول على دعم كامل لمتصفح Internet Explorer 8 والمتصفحات الأخرى القديمة فعليك استخدام polyfill لـCSS3 Media Queries (Respond.js، HTML5 shim) والذي يمكننا من استخدام عناصر HTML5. كما أنّه يجب عليك استخدام وسم <meta> مناسب داخل وسم <head> حتى نتأكد بأنّ متصفح IE لا يعمل في وضع التوافقية (compatibility mode). يجب أن يبدو وسم <head> كما في الأسفل: <head> ... <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> </head>في حالة Respond.js كن حذرًا من بعض الأمور في بيئات التطوير. الخطأ 10: تجاهل أفضل الممارسات (best practices)واحد من أكثر الأسئلة شيوعًا على موقع Stack Overflow هو كيفية جعل القوائم المنسدلة (dropdown menu) تظهر عندما يقوم المستخدم بتمرير مؤشر الفأرة فوق العنصر (hover) بدلًا من النقر عليه. وصحيح أنّ حل هذا السؤال ليس بالأمر الصعب ويمكن حله باستخدام CSS فقط ولكن هذا الأمر غير محبذ، فهذه الميزة تم التخلص منها في هذا الإطار بشكل متعمد وكان قرار إزالتها قد تم من قبل فريق تطوير الإطار نفسه. وكما قلنا سابقًا فحل السؤال ليس صعبًا ولكن يجب عليك معرفة التداعيات التي تأتي معها ويجب عليك أيضًا أن تعرف بأنّ هناك ممارسات جيدة يجب عليك اتباعها خصوصًا في أُطر العمل التي تكون أولويتها التطوير للهواتف. والسبب خلف ذلك هو أنّ جعل الأشياء تعمل عندما يقوم المستخدم بوضع مؤشر الفأرة فوقها (hover) لا يساعد المستخدمين الذين يعملون على أجهزة تعمل باللمس (touch). ففي هذه الأجهزة لا يوجد شيء اسمه "hover" يوجد فقط اللمس، وبالتالي فإنّ ذلك سيؤدي إلى الإضرار بمستخدمي الأجهزة التي تعمل باللمس. خلاصةأتمنى بأن يساعدك هذا المقال على تفادي بعض المشاكل والأخطاء الشائعة وتوضيح بعض المفاهيم الخاطئة. وضع في الحسبان بأنّ إطار Bootstrap لن يكون مناسبًا لكل مطور أو حتى أي مشروع، وعندما تقوم باختيار أي إطار عمل فإنّه يجب عليك أن تقرأ التوثيق الخاص به بكل تروٍ وأن تقضي بعض الوقت في التعامل معه حتى تعلم كيف يعمل. ترجمة -وبتصرّف- للمقال The 10 Most Common Bootstrap Mistakes لصاحبته TOMISLAV BACINGER.
    1 نقطة
×
×
  • أضف...