البداية في الجافا سكربت

بما أنك الآن قد تعرفت على المفهوم العام للغةْ جافاسكريبت, و ما الذي يمكن أن تعمله بها, سنقوم الآن بإعطائك كورس مكثف في أساسيات جافاسكريبت من خلال دروس تعتمد تماما على التجربة العملية. ستقوم الآن و خطوة بخطوة بعمل لعبةْإحزر الرقم .

المتطلبات اﻷساسية: فهم أساسيات الحاسوب، فهم أساسيات HTML و CSS, وفهم ما هي الجافا سكربت.
الهدف: أخذ قليل من الخبرة في كتابة بعض الجافا سكربت، وفهم القليل من اﻷساسيات لفهم كتابة برنامج بالجافا سكربت  .

لا تتوقع أن تفهم كل تفاصيل الكود في الوقت الحالي __ نحن نريد أن نقدم لك المباديء العليا اﻵن، وإعطاؤك فكرة عن كيفية عمل الجافاسكربت ( وأي لغة برمجة أخرى ). في المقالات اللاحقة ، سوف نرى كل هذه الميزات بكثير من التفصيل!

ملحوظة: العديد من ملامح الكود سوف تراها في الجافا سكربت كما في اللغات البرمجية اﻵخرى __ الدوال ، الحلقات التكرارية، إلخ. بنية الكود تبدو مختلفة ، ولكن المبدأ واحد ﻻ يتغير .

فكر مثل المُبَرْمِج

واحد من اﻷشياء الصعبة في تعلم البرمجة ليس بنية الكود، ولكن كيف تطبق هذا الكود لحل المشاكل في العالم الحقيقي. أنت تحتاج للبدء في التفكير مثل المُبَرْمِج__ عمومًا هذا يتضمن النظر في وصف ماذا يحتاج برنامجك لكي يعمل, وعلى ماذا يعمل. ملامح الكود تحتاج ﻷن تحقق هذه اﻷشياء، وكيفية جعلهم يعملون معًا.

المتطلبات مزيج من العمل الجاد ، الخبرة في تركيب الجملة البرمجية ، و التدريب بجانب قليل من اﻹبداع. كلما قمت بكتابة الكود ، كلما كان ذلك أفضل . ﻻ نعدك أن تطور " عقل المبرمج " في خمسة دقائق، ولكن سوف نعطيك الكثير من الفرص للتدريب على التفكير مثل المُبَرْمِج خلال هذه الدورة .

مع أخذ ذلك في الاعتبار ، دعنا نأخذ مثال سوف ننشأه في هذا المقال، ومراجعة العملية العامة لتقسيمها إلى مهام ملموسة . 

مثال __ لعبة تخمين الرقم

في هذا المقال سنعرض لك كيفية بناء لعبة بسيطة كما في هذا المثال :

جرب اللعب __ تعرف بنفسك على اللعبة قبل أن تمضي قُدُمًا .

دعنا نتخيل رئيسك في العمل أعطاك المختصر التالي ﻹنشاء هذه اللعبة :

أريد منك أن تنشيء لعبة بسيطة وهي لعبة تخمين الرقم. يجب اختيار رقم عشوائي بين 1 و 100 ،  ثم تحدي اللاعب لتخمين الرقم في 10 مرات. بعد كل مرة يجب إخبار اللاعب هل الرقم صحيح أم خطأ  — و إذا كانت اﻷرقام المخمنة خطأ ، فهل كان التخمين قريب جدًا أم بعيد جدًا . يجب أن يخبر اللاعب أيضًا ما اﻷرقام التي خمنها سابقًا . اللعبة تنتهي عندما يخمن اللاعب الرقم الصحيح، أو تستمر اللعبة حتي نهاية عدد المرات. عندما تنتهي اللعبة يجب إعطاء اللاعب خيار بدء اللعبة مرة أخرى .

بناءًا على النظر في هذا المختصر ، أول شيء يمكننا فعله هو البدء في تقسيمها إلى مهام بسيطة قابلة للتنفيذ، مثل عقلية المبرمج :

  1. أنشيء رقم عشوائي بين 1 و 100 .
  2. سجل الرقم الذي أدخله اللاعب . بداية من رقم 1 .
  3. أعطِ اللاعب طريقة لتخمين ما هو الرقم .
  4. بمجرد أن يدخل اللاعب الرقم ، سجل أول رقم بحيث يستطيع اللاعب أي يرى تخمينات السابقة.
  5. ثم ، تأكد ما إذا كان الرقم صحيح.
  6. إذا كان صحيحًا :
    1. اعرض رسالة التهنئة .
    2. امنع اللاعب من كتابة تخمينات أخرى ( ﻷن هذا سيفسد اللعبة) .
    3. اعرض للاعب أن يبدأ اللعبة مرة أخرى .
  7. إذا كان خطأ واللاعب لديه مرات أخرى :
    1. أخبر اللاعب أن التخمين خطأ .
    2. اسمح للاعب بإدخال تخمين آخر.
    3. قم بزيادة المحاوﻻت بمقدار 1 .
  8. إذا كان خطأ واللاعب ليس لدي مرات أخرى:
    1. أخبر اللاعب أن اللعبة انتهت .
    2. امنع اللاعب من كتابة تخمينات أخرى ( ﻷن هذا سيفسد اللعبة) .
    3. اعرض للاعب أن يبدأ اللعبة مرة أخرى .
  9. عندما يُعاد تشغيل اللعبة ، تأكد من إعادة تعيين اللعبة وواجهة المستخدم ، ثم نفذ الخطوة رقم 1 .

دعنا نبدأ اﻵن ، لنرى كيف نستطيع أن نحول هذه الخطوات إلى كود، وننشيء هذا المثال ، ونستكشف ميزات الجافا سكربت في طريقنا :

اﻹعداد اﻷولي

للبدء في الحل ، نفضل أن تأخذ نسخة من ملف , number-guessing-game-start.html  (هنا يمكن رؤية المثال الحي). افتح الملف في محرر النصوص الخاص بك وفي متصفح الويب.سترى عنوان رئيسي وفقرة التعليمات و نموذج ﻹدخال التخمينات ، ولكن هذا النموذج حاليًا لن يقوم بعمل أي شيء .

المكان حيث سنضيف الكود الخاص بنا بداخله  <script> يوجد في آخر ملف HTML :

<script>

  // Your JavaScript goes here

</script>

إضافة المتغيرات لتخزين البيانات الخاصة بنا

دعونا نبدأ. قبل كل شيء ، أضف اﻷسطر التالية بداخل عنصر<script> :

let randomNumber = Math.floor(Math.random() * 100) + 1;

const guesses = document.querySelector('.guesses');
const lastResult = document.querySelector('.lastResult');
const lowOrHi = document.querySelector('.lowOrHi');

const guessSubmit = document.querySelector('.guessSubmit');
const guessField = document.querySelector('.guessField');

let guessCount = 1;
let resetButton;

في هذا القسم من الكود فقد هيئنا المتغيرات والثوابت التي سنحتاجها لتخزين بيانات برنامجنا. المتغيرات تحتوي بشكل أساسي على قيم ( مثل الأرقام، النصوص). ﻹنشاء متغير نكتب الكلمة let  ( أو var ) متبوعة باسم المتغير ( للمزيد عن الاختلاف بين الكلمات المفتاحية في هذه المقالة ). الثوابت تستخدم لتخزين قيم غير قابلة للتغيير أو ﻻ تتغير وتكتب الثوابت بعد الكلمة المفتاحية const. في هذه الحالة ، نستخدم الثوابت لتخزين مراجع ﻷجزاء من واجهة المستخدم ; النص بداخل بعض هذه الثوابت ممكن أن يتغير ، ولكن عنصر HTML  يبقى كما هو .

تستطيع تعيين قيمة للمتغير أو الثابت بعد علامة يساوي (=) متبوعة بالقيمة التي تريدها .

في مثالنا :

  • المتغير اﻷول — randomNumber — يحدد رقم عشوائي بين 1 و 100 ، حيث تم حسابه باستخدام خوارزمية رياضية .
  • أول ثلاثة ثوابت هي لتخزين مرجع للفقرات في HTML ، وتستخدم ﻹدخال قيم في عنصر الفقرات في الكود ( ﻻحظ أنهم بداخل عنصر <div> ، الذي يستخدم لتحديد الثلاثة لتهيئتهم في وقت ﻻحق ، عندما نعيد تشغيل اللعبة)
    <div class="resultParas">
      <p class="guesses"></p>
      <p class="lastResult"></p>
      <p class="lowOrHi"></p>
    </div>
  • الثابتين التاليين يخزنان مراجع لنص حقل اﻹدخال و زر اﻹرسال حيث يستخدم للتحكم في إرسال الرقم الذي تم تخمينه .
  • <label for="guessField">Enter a guess: </label><input type="text" id="guessField" class="guessField">
    <input type="submit" value="Submit guess" class="guessSubmit">
  • آخر متغيرين لدينا يخزنان عدد مرات التخمين بداية من المرة 1 ( يستخدم لحفظ كم مرة قام اللاعب بالتخمين )، ومرجع لزر التهيئة (حيث سيكون موجود فيما بعد ) .

ملحوظة: سوف تتعمل المزيد عن المتغيرات / الثوابت فيما بعد في هذه الدورة ، بداية من المقال التالي .

الدوال

ثم ، أضف التالي أسفل كود الجافا سكربت الذي كتبناه باﻷعلى :

function checkGuess() {
  alert('I am a placeholder');
}

الدوال هي جزء من الكود يمكن إعادة استخدامه حيث تستطيع كتابة مرة واحدة واستدعاؤه مرة أخرى ومرة أخرى، وحفظ الكود الذي نحتاج لتكراره دائمًا .هذا حقًا مفيد.هناك عدة طرق لتعريف الدوال، ولكن اﻵن سنركز على نوع بسيط. هنا عرَّفنا الدالة باستخدام الكلمة المفتاحية  function, متبوعة بالاسم, مع اﻷقواس بعدها . بعد ذلك وضعنا اﻷقواس المعقوفة ({ }). بداخل اﻷقواس المعقوفة نكتب الكود الذي نريده لكي يعمل عندما نستدعي هذه الدالة.

عندما نريد تشغير الكود ، نكتب اسم الدالة متبوعًا باﻷقواس.

دعنا نحاول اﻵن. احفظ الكود و أعد تحميل الصفحة في المتصفح. ثم اذهب إلى   developer tools JavaScript console, وأدخل السطر التالي :

checkGuess();

بعد الضغط على Return/Enter, يجب أن ترى تحذير يقول لك "I am a placeholder" لقد عرَّفنا الدالة في الكود الخاص بنا حيث تنشيء تحذير عند استدعائها.

ملحوظة: سوف تتعلم المزيد عن الدوال في هذه الدورة .

العمليات الرياضية

العمليات الرياضية في الجافا سكربت تسمح لنا أن نجري اختبارات، حل الرياضيات، ربط مجموعة كلمات ونصوص مع بعضهم البعض، وأشياء أخرى.

إذا لم تقم بذلك بالفعل ، احفظ الكود الخاص بك، أعد تحميل الصفحة في المتصفح الخاص بك، وافتح developer tools JavaScript console .بعد ذلك نستطيع الكتابة كما في المثال التالي __ اكتب كل واحد من أعمدة "المثال" كما هو موضح تمامًا، اضغط Return/Enter بعد كل واحد، وانظر ما هي النتائج التي ظهرت :

أوﻻً دعنا نلقى نظرة على العمليات الحسابية ، على سبيل المثال :

العملية المسمى مثال
+ الجمع 6 + 9
- الطرح 20 - 15
* الضرب 3 * 7
/ القسمة 10 / 5

أيضًا تستطيع استخدام علامة + لربط النصوص معًا ( في البرمجة، هذا يسمى التسلسل). جرب إدخال السطور التالية ، واحدًا تلو الآخر :

let name = 'Bingo';
name;
let hello = ' says hello!';
hello;
let greeting = name + hello;
greeting;

هناك أيضًا بعض العمليات الحسابية المختصرة ، تسمى زيادة عوامل التخصيص. على سبيل المثال ، إذا أردت إضافة نص جديد لنص موجود بالفعل وترى النتيجة ، تستطيع كتابة هذا :

name += ' says hello!';

هذا يعادل :

name = name + ' says hello!';

عند استخدام حالة صح/ خطأ ( على سبيل المثال بداخل الحاﻻت الشرطية __ انظر below ) نستخدم عمليات المقارنة . على سبيل المثال :

العملية المسمى مثال
=== المساواة الصارمة(هل هي نفسها بالضبط؟)
5 === 2 + 4 // false
'Chris' === 'Bob' // false
5 === 2 + 3 // true
2 === '2' // false; number versus string
!== عدم المساواة (أليست هي نفسها؟)
5 !== 2 + 4 // true
'Chris' !== 'Bob' // true
5 !== 2 + 3 // false
2 !== '2' // true; number versus string
< أقل من
6 < 10 // true
20 < 10 // false
> أكبر من
6 > 10 // false
20 > 10  // true

الحاﻻت الشرطية

بالعودة إلى دالة checkGuess() ، أعتقد أنه من المكن قول أننا ﻻ نريدها ﻹظهار رسالة placeholder . نحن نريدها لفحص هل تخمين اللاعب صحيح أم غير صحيح،  واﻹستجابة بشكل مناسب.

في هذه النقطة، استبدل دالة checkGuess() بهذا بدلًا من ذلك :

function checkGuess() {
  let userGuess = Number(guessField.value);
  if (guessCount === 1) {
    guesses.textContent = 'Previous guesses: ';
  }
  guesses.textContent += userGuess + ' ';

  if (userGuess === randomNumber) {
    lastResult.textContent = 'Congratulations! You got it right!';
    lastResult.style.backgroundColor = 'green';
    lowOrHi.textContent = '';
    setGameOver();
  } else if (guessCount === 10) {
    lastResult.textContent = '!!!GAME OVER!!!';
    setGameOver();
  } else {
    lastResult.textContent = 'Wrong!';
    lastResult.style.backgroundColor = 'red';
    if(userGuess < randomNumber) {
      lowOrHi.textContent = 'Last guess was too low!';
    } else if(userGuess > randomNumber) {
      lowOrHi.textContent = 'Last guess was too high!';
    }
  }

  guessCount++;
  guessField.value = '';
  guessField.focus();
}

هذا كثير من التعليمات البرمجية __ حسنًا ! دعنا ننتقل إلى كل قسم وشرح ما يفعله.

  • السطر اﻷول (سطر رقم 2 في اﻷعلى) يعلن عن متغير يسمى userGuess ويهييء قيمته إلى القيمة المدخلة في حقل النصوص. أيضًا نستطيع أخذ هذه القيمة بواسطة دالة Number() ، فقط للتأكد من أن القيمة بالفعل رقم .
  • في السطر التالي، سنقابل أول كود من الحالات الشرطية (سطر 3-5 في اﻷعلى). كود الحالة الشرطية يسمح لك بتشغيل الكود بشكل انتقائي، بالاعتماد على حالة شرطية مؤكدة صح أو خطأ. يشبه هذا قليلًا الدالة، لكنه ليس بدالة. ببساطة لبدء كود الحالة الشرطية نكتب الكلمة المفتاحية if ، ثم بعض اﻷقواس، ثم اﻷقواس المعقوفة. بداخل اﻷقواس نكتب الشرط. إذا كان الشرط صحيح true ، سوف يشغل الكود بداخل اﻷقواس المعقوفة. وإذا كان غير ذلك ، لن ينفذ شيء وسينتقل لتشغيل باقي الكود. في حالتنا هذه الشرط سوف يتحقق ما إذا كان متغير guessCount يساوي 1 (أي ما إذا كانت هذه هي المرة اﻷولى للاعب أم ﻻ):
  • guessCount === 1

إذا كان اﻷمر كذلك، فإننا نجعل نص فقرة التخمينات مساويًا لــ "Previous guesses: ". وإذا كان غير ذلك ، فلن نفعل.

  • السطر 6 يضيف قيمة  userGuess في نهاية الفقرة guesses ، باﻹضافة إلى مسافة لذلك ستكون هناك مسافة بين كل تخمين .
  • الكود التالي (السطور من 8-24 في اﻷعلى) تقوم بالقليل من المراجعات :
    • أولًا if(){} تفحص ما إذا كان تخمين المستخدم مساويًا لــ randomNumber الذي عرفناه في أعلى كود الجافاسكربت. إذا صحيحًا إذا اللاعب قام بالتخمين الصحيح وربح في هذه اللعبة، لذلك يتم عرض رسالة التهاني ، ويتم مسح مربع النص الذي يحتوي على تخمين عالي/منخفض، ويتم تشغيل دالة setGameOver() التي سنشرحها فيما بعد.
    • اﻵن لدينا حالة شرطية أخرى باستخدام else if(){}. حيث إنها تفحص ما إذا كانت هذه المرة هي آخر مرة للاعب أم ﻻ. إذا كانت آخر مرة فإن هذا البرنامج يفعل نفس اﻷشياء في الكود السابق، مع عرض رسالة انتهت اللعبة بدلاً من رسالة التهنئة.
    • الجزء اﻷخير يحتوي على ( else { } )الذي يحتوي على الكود الذي يعمل فقط في حالة الحاﻻت الشرطية( مثل أن اللاعب لم يخمن الرقم الصحيح، ولكن تبقى له المزيد من التخمينات). في هذه الحالة سوف نخبره بأن تخمينه خطأ ، ثم نشغل حالة شرطية أخرى حيث تفحص ما إذا كان التخمين عالى أو أقل من اﻹجابة، وعرض رسالة أخرى تخبر اللاعب إذا كان تخمينه أعلى أو أقل .
  • آخر ثلاثة أسطر في هذه الدالة ( السطور من 26-28 في الأعلى)تكون مستعدة ﻹرسال التخمين. لقد أضفنا 1 لمتغير guessCount لحساب استهلاك اللاعب عدد أدواره(++ هي عملية زيادة__ أي زيادة بمقدار 1 في المرة)، وتفريغ قيم حقل النصوص ، والاستعداد للدور القادم من التخمين .

اﻷحداث

At this point we have a nicely implemented checkGuess() function, but it won't do anything because we haven't called it yet. Ideally we want to call it when the "Submit guess" button is pressed, and to do this we need to use an event. Events are things that happen in the browser — a button being clicked, a page loading, a video playing, etc. — in response to which we can run blocks of code. The constructs that listen out for the event happening are called event listeners, and the blocks of code that run in response to the event firing are called event handlers.

Add the following line below your checkGuess() function:

guessSubmit.addEventListener('click', checkGuess);

Here we are adding an event listener to the guessSubmit button. This is a method that takes two input values (called arguments) — the type of event we are listening out for (in this case click) as a string, and the code we want to run when the event occurs (in this case the checkGuess() function). Note that we don't need to specify the parentheses when writing it inside addEventListener()).

Try saving and refreshing your code now, and your example should work — to a point. The only problem now is that if you guess the correct answer or run out of guesses, the game will break because we've not yet defined the setGameOver() function that is supposed to be run once the game is over. Let's add our missing code now and complete the example functionality.

Finishing the game functionality

Let's add that setGameOver() function to the bottom of our code and then walk through it. Add this now, below the rest of your JavaScript:

function setGameOver() {
  guessField.disabled = true;
  guessSubmit.disabled = true;
  resetButton = document.createElement('button');
  resetButton.textContent = 'Start new game';
  document.body.appendChild(resetButton);
  resetButton.addEventListener('click', resetGame);
}
  • The first two lines disable the form text input and button by setting their disabled properties to true. This is necessary, because if we didn't, the user could submit more guesses after the game is over, which would mess things up.
  • The next three lines generate a new <button> element, set its text label to "Start new game", and add it to the bottom of our existing HTML.
  • The final line sets an event listener on our new button so that when it is clicked, a function called resetGame() is run.

Now we need to define this function too! Add the following code, again to the bottom of your JavaScript:

function resetGame() {
  guessCount = 1;

  var resetParas = document.querySelectorAll('.resultParas p');
  for (var i = 0 ; i < resetParas.length ; i++) {
    resetParas[i].textContent = '';
  }

  resetButton.parentNode.removeChild(resetButton);

  guessField.disabled = false;
  guessSubmit.disabled = false;
  guessField.value = '';
  guessField.focus();

  lastResult.style.backgroundColor = 'white';

  randomNumber = Math.floor(Math.random() * 100) + 1;
}

This rather long block of code completely resets everything to how it was at the start of the game, so the player can have another go. It:

  • Puts the guessCount back down to 1.
  • Clears all the information paragraphs.
  • Removes the reset button from our code.
  • Enables the form elements, and empties and focuses the text field, ready for a new guess to be entered.
  • Removes the background color from the lastResult paragraph.
  • Generates a new random number so that you are not just guessing the same number again!

At this point you should have a fully working (simple) game — congratulations!

All we have left to do now in this article is talk about a few other important code features that you've already seen, although you may have not realized it.

Loops

One part of the above code that we need to take a more detailed look at is the for loop. Loops are a very important concept in programming, which allow you to keep running a piece of code over and over again, until a certain condition is met.

To start with, go to your browser developer tools JavaScript console again, and enter the following:

for (var i = 1 ; i < 21 ; i++) { console.log(i) }

What happened? The numbers 1 to 20 were printed out in your console. This is because of the loop. A for loop takes three input values (arguments):

  1. A starting value: In this case we are starting a count at 1, but this could be any number you like. You could replace the letter i with any name you like too, but i is used as a convention because it's short and easy to remember.
  2. An exit condition: Here we have specified i < 21 — the loop will keep going until i is no longer less than 21. When i reaches 21, the loop will no longer run.
  3. An incrementor: We have specified i++, which means "add 1 to i". The loop will run once for every value of i, until i reaches a value of 21 (as discussed above). In this case, we are simply printing the value of i out to the console on every iteration using console.log().

Now let's look at the loop in our number guessing game — the following can be found inside the resetGame() function:

var resetParas = document.querySelectorAll('.resultParas p');
for (var i = 0 ; i < resetParas.length ; i++) {
  resetParas[i].textContent = '';
}

This code creates a variable containing a list of all the paragraphs inside <div class="resultParas"> using the querySelectorAll() method, then it loops through each one, removing the text content of each.

A small discussion on objects

Let's add one more final improvement before we get to this discussion. Add the following line just below the var resetButton; line near the top of your JavaScript, then save your file:

guessField.focus();

This line uses the focus() method to automatically put the text cursor into the <input> text field as soon as the page loads, meaning that the user can start typing their first guess right away, without having to click the form field first. It's only a small addition, but it improves usability — giving the user a good visual clue as to what they've got to do to play the game.

Let's analyze what's going on here in a bit more detail. In JavaScript, everything is an object. An object is a collection of related functionality stored in a single grouping. You can create your own objects, but that is quite advanced and we won't be covering it until much later in the course. For now, we'll just briefly discuss the built-in objects that your browser contains, which allow you to do lots of useful things.

In this particular case, we first created a guessField variable that stores a reference to the text input form field in our HTML — the following line can be found amongst our variable declarations near the top:

var guessField = document.querySelector('.guessField');

To get this reference, we used the querySelector() method of the document object. querySelector() takes one piece of information — a CSS selector that selects the element you want a reference to.

Because guessField now contains a reference to an <input> element, it will now have access to a number of properties (basically variables stored inside objects, some of which can't have their values changed) and methods (basically functions stored inside objects). One method available to input elements is focus(), so we can now use this line to focus the text input:

guessField.focus();

Variables that don't contain references to form elements won't have focus() available to them. For example, the guesses variable contains a reference to a <p> element, and guessCount contains a number.

Playing with browser objects

Let's play with some browser objects a bit.

  1. First of all, open up your program in a browser.
  2. Next, open your browser developer tools, and make sure the JavaScript console tab is open.
  3. Type in guessField and the console will show you that the variable contains an <input> element. You'll also notice that the console autocompletes the names of objects that exist inside the execution environment, including your variables!
  4. Now type in the following:
    guessField.value = 'Hello';
    The value property represents the current value entered into the text field. You'll see that by entering this command, we've changed the text in the text field!
  5. Now try typing in guesses and pressing return. The console will show you that the variable contains a <p> element.
  6. Now try entering the following line:
    guesses.value
    The browser will return undefined, because paragraphs don't have the value property.
  7. To change the text inside a paragraph, you need the textContent property instead. Try this:
    guesses.textContent = 'Where is my paragraph?';
  8. Now for some fun stuff. Try entering the below lines, one by one:
    guesses.style.backgroundColor = 'yellow';
    guesses.style.fontSize = '200%';
    guesses.style.padding = '10px';
    guesses.style.boxShadow = '3px 3px 6px black';
    Every element on a page has a style property, which itself contains an object whose properties contain all the inline CSS styles applied to that element. This allows us to dynamically set new CSS styles on elements using JavaScript.

Finished for now...

So that's it for building the example. You got to the end — well done! Try your final code out, or play with our finished version here. If you can't get the example to work, check it against the source code.

في هذه الوحدة