חלק VII: מטה-מחלקות • יחידה 18.1 סגירת מעגל ההפשטה של מודל העצמים

ייצוג מחלקה באמצעות עצם: אם מחלקה היא עצם — מי המחלקה שלה?

הכרת מושג ה"מטה-מחלקה" (Metaclass) כיחידת ההפשטה המייצגת מחלקה של מחלקה, תכונת האנונימיות (Implicit), וחקירת שרשרת ההודעות true class... עד להתכנסות למעגל סגור (Fixed Point).

🧬
🧠

מודל מנטלי ועיקרון מנחה: כש"הכל הוא עצם" פוגש את "כל עצם הוא מופע של מחלקה"

💡 האנלוגיה המוחשית

תבנית אפייה מייצרת עוגיות, אבל מי ייצר את תבנית האפייה עצמה? מפעל ליצירת תבניות! ב-Smalltalk, עוגייה היא עצם רגיל, תבנית האפייה היא המחלקה (Class), והמפעל שמייצר את התבנית הזו הוא המטה-מחלקה (Metaclass)!

⚖️ חוק הברזל הפדגוגי

ב-Smalltalk כל דבר במערכת הוא עצם (כולל המחלקות Object, Color, Point), וכל עצם הוא בהכרח מופע של מחלקה. לכן כל מחלקה היא מופע של מטה-מחלקה אנונימית שהגישה אליה נעשית על ידי שליחת ההודעה class אל עצם המחלקה.

🎯 תובנת המפתח

שרשור חוזר של ההודעה class (כמו true class class class...) אינו ממשיך לאינסוף! החל מהצעד השלישי והרביעי אנו מתכנסים למעגל סגור (Fixed Point) המתחלף לסירוגין בין Metaclass לבין Metaclass class.

1. שאלת היסוד שסוגרת את מעגל העקביות ב-Smalltalk

איך שני כללי היסוד שלנו מובילים בהכרח להולדת המושג "מטה-מחלקה" (Metaclass)

אנחנו מגיעים עכשיו אל שיא הארכיטקטורה של Smalltalk — המקום שבו כל חלקי הפאזל שבנינו מתחברים למערכת אחת שלמה, עקבית וסגורה. בוא נזכיר לעצמנו את עקרון היסוד שליווה אותנו מהרגע הראשון ב-Smalltalk: כל דבר במערכת הוא עצם (Everything is an object), וכל עצם הוא בהכרח מופע של מחלקה (Every object is an instance of a class).

עכשיו בוא נחשוב יחד כמו מהנדסי שפות תכנות: אם כל דבר במערכת הוא עצם, נובע מכך ישירות שגם המחלקות עצמן (כגון Object, Color, Point או True) הן עצמים חיים בזיכרון! אנחנו הרי שולחים להן הודעות כל הזמן (כמו Point new או Color blue). אבל אם מחלקה היא עצם, מיד מתעוררת השאלה הלוגית המתבקשת: של איזו מחלקה היא מופע?

💎

הגדרת המושג: מטה-מחלקה (Metaclass)

מחלקה שהמופעים שלה הם בעצמם מחלקות נקראת מטה-מחלקה (Metaclass). זוהי יחידת ההפשטה המטפלת במנגנון של "מחלקה של מחלקה".

🕵️ מטה-מחלקות הן אנונימיות (Implicit): למטה-מחלקה אין שם עצמאי גלובלי משלה במערכת! אז איך אנחנו ניגשים אליה? אנחנו פונים אל עצם המחלקה ושולחים לו את ההודעה אונארית class. למשל: שליחת class למחלקה Color מחזירה את המטה-מחלקה שלה, שנקראת פשוט Color class, ושליחת class ל-Object מחזירה את Object class.

2. ניסוי מחשבתי חי: שרשור ההודעה true class...

מה קורה כשאנחנו שואלים שוב ושוב "ומהי המחלקה של המחלקה הזו?" לאורך 7 שלבים עוקבים?

כדי לראות במו עינינו איך סביבת Squeak עונה על השאלה "מי המחלקה של המטה-מחלקה?", בוא ניקח את העצם הבוליאני הפשוט true ונשלח אליו את ההודעה class שוב ושוב בשרשרת של 7 שלבים:

1
true class

המופע הבוליאני true הוא מופע יחיד של המחלקה True (תת-מחלקה של Boolean). לכן מוחזרת המחלקה True.

2
true class class

כעת אנו שואלים את המחלקה True מהי המחלקה שלה. מוחזרת המטה-מחלקה האנונימית שלה: True class.

3
true class class class

מהי המחלקה של מטה-מחלקה (True class)? כל המטה-מחלקות במערכת הן מופעים של מחלקה אחת מיוחדת: מוחזרת המחלקה Metaclass!

4
true class class class class

ומהי המחלקה של Metaclass? מכיוון שגם Metaclass היא מחלקה, יש לה מטה-מחלקה משלה: מוחזרת Metaclass class!

5–7
true class class class class class ➔ Metaclass ➔ Metaclass class ➔ Metaclass

בשלב 5 אנחנו שואלים: מהי המחלקה של Metaclass class? מכיוון ש-Metaclass class היא בעצמה מטה-מחלקה, היא מופע של Metaclass!
בשלבים 6 ו-7 (וכך עד אינסוף) אנו נכנסים למעגל סגור (Fixed Point) המתחלף לסירוגין בין Metaclass class לבין Metaclass — וכך נמנעת רגרסיה אינסופית!

עזר גרפי 18.1 • שרשרת ההודעות class והמעגל הסגור

מסלול ההתכנסות מהמופע הבוליאני true אל לולאת ה-Fixed Point של Metaclass

Fixed-Point Convergence
true מופע סופי 1. class True מחלקה (Class) 2. class True class מטה-מחלקה אנונימית 3. class Metaclass מחלקת כל המטה-מחלקות Metaclass class מטה-מחלקה של Metaclass 4, 6... class 5, 7... class
🔍

מיני-סימולציה 18.1: בודק המופעים והמטה-מחלקות האנונימיות

לחץ על כל ישות בזיכרון כדי לראות של מי היא מופע וכיצד ניגשים למטה-מחלקה שלה
🕹️
סימולציה אינטראקטיבית גדולה 18.1

קונסולת "מדרגות ה-Class" ב-Squeak: שרשור true class... (שלבים 1 עד 7)

בחר את עצם ההתחלה או לחץ על "שלח הודעת class נוספת (+)" כדי לטפס שלב אחר שלב בסולם ההפשטה ולראות בזמן אמת מתי המערכת נכנסת למעגל הסגור (Fixed Point) בין Metaclass ל-Metaclass class:

מופע התחלתי:
true class
תוצאת השערוך ב-Squeak (Print it): שלב 1 מתוך 7
True
⚡

הגשר הנרטיבי: ראינו ששרשור class עובר דרך 5 רמות עד למעגל הסגור – אבל למה בכלל צריך 5 רמות?

אולי אתה שואל את עצמך עכשיו: "רגע, למה בעצם אנחנו צריכים גם מופע, גם מחלקה, גם מטה-מחלקה פרטית, גם Metaclass וגם Metaclass class? האם אי אפשר היה להסתפק במערכת פשוטה יותר של רמה אחת, שתיים או שלוש?" בלשונית הבאה נצא למסע היסטורי והנדסי מרתק לאורך 5 ארכיטקטורות של מערכות עצמים (משפת Self ועד Squeak), ונראה בדיוק איזו מגבלה בכל רמה הכריחה אותנו לטפס לרמה החמישית!

סוף יחידה 18.1 • ייצוג מחלקה באמצעות עצם
חלק VII: מטה-מחלקות • יחידה 18.2–18.7 אבולוציית מערכות העצמים

סיווג עצמים למטה-רמות (Meta-levels) והתפתחות מערכות העצמים מרמה 1 ועד 5 רמות

שלוש שכבות העצמים (מופעים סופיים, מחלקות ומטה-מחלקות בדוגמת המחזות והרומנים), וניתוח מעמיק של 5 ארכיטקטורות: Self (רמה 1), Eiffel ו-++C (רמה 2), Smalltalk-76 ו-Little Smalltalk (רמה 3), LOOPS ו-ObjVlisp (רמה 4), ו-Squeak / Smalltalk-80 (רמה 5).

🏛️
🧠

מודל מנטלי ועיקרון מנחה: כדי שלכל מחלקה יהיו בנאים ומתודות מחלקה משלה, היא חייבת מטה-מחלקה פרטית!

💡 האנלוגיה המוחשית

המופע "אוליבר טוויסט" הוא ספר קריאה סופי שאינו יכול לייצר ספרים חדשים. המחלקה "רומן" (Novel) מייצרת ספרים ספציפיים, והמטה-מחלקה (Class / Metaclass) היא זו שמייצרת את המחלקות עצמן ("רומן", "מחזמר").

⚖️ חוק הברזל הפדגוגי

במערכת בת 3 רמות (כמו Smalltalk-76), כל המחלקות הן מופעים של מטה-מחלקה יחידה (Class), ולכן לא ניתן להגדיר בנאים ייחודיים לכל מחלקה (כמו Point x:y:) מבלי לחשוף אותם לכל שאר המחלקות במערכת!

🎯 תובנת המפתח

מודל 5 הרמות של Squeak (Explicit Metaclass) מעניק לכל מחלקה מטה-מחלקה פרטית משלה בהיררכיה מקבילה, וקושר את כל המטה-מחלקות למחלקה Metaclass בקשר מעגלי סגור עם Metaclass class.

1. סעיף 18.2: סיווג עצמים לשלוש שכבות היררכיות (Meta-levels)

הבחנה בין מופעים סופיים (Terminal Instances), מחלקות (Classes) ומטה-מחלקות (Metaclasses)

כדי שנבין לעומק מדוע סביבת Squeak בנויה דווקא במודל של 5 רמות, בוא נסווג תחילה את העצמים בעולם התוכנה שלנו לשלוש שכבות היררכיות עקרוניות לפי יכולת היצירה (Instantiation) שלהם:

שכבה 1 · Terminal Instances

1. עצמים פשוטים / מופעים סופיים

עצמים בקצה השרשרת שאינם מסוגלים לייצר עצמים חדשים. למשל: מופעים של תווים, מחרוזות, נקודות, או בדוגמת היצירות הספרותיות והבימתיות: המופעים "אותלו", "מקבת", "כטוב בעיניכם" (מופעי מחזמר/מחזה) ו-"1984", "אוליבר טוויסט", "מלחמה ושלום" (מופעי רומן).

שכבה 2 · Classes

2. מחלקות (עצמים מייצרי מופעים)

עצמים המסוגלים לייצר מופעים סופיים. בדוגמה שלנו אלו הן המחלקות "מחזמר" ו-"רומן" (Novel), או בשפה שלנו המחלקות Point, Color ו-String.

שכבה 3 · Metaclasses

3. מטה-מחלקות (מייצרות מחלקות)

עצמים המסוגלים לייצר מחלקות חדשות (כגון המחלקה הגנרית Class או מטה-המחלקות ב-Squeak). המופעים שלהן הם המחלקות מהשכבה השנייה!

2. סעיפים 18.3–18.7: התפתחות מערכות העצמים – מרמה 1 ועד 5 רמות

איך שפות התכנות מונחות העצמים נבדלות זו מזו במספר ה"רמות" במודל העצמים שלהן, ומה פתר כל שלב?

18.3 · רמה 1: מערכת של עצמים בלבד (Prototype-based) דוגמאות: שפת Self, JavaScript (במודל המקורי)

אפיון: מערכת "שטוחה" ללא מחלקות כלל. כל עצם מתאר את עצמו באופן עצמאי (טבלה של שמות וערכים — שדות ומתודות ייעודיים), ויצירת עצמים חדשים נעשית באמצעות שכפול (Cloning) של עצם אב-טיפוס קיים (Prototype), תוך שיתוף התנהגות באמצעות מצביעי parent ו-traits.

18.4 · רמה 2: מערכת עצמים בת 2 רמות דוגמאות: שפת Eiffel (אייפל), ++C המסורתית

אפיון: קיימת הבחנה ברורה בין עצמים למחלקות (עצמים מתוארים על ידי מחלקות), אך המחלקות עצמן אינן עצמים בזמן ריצה! הן מתקיימות כיישויות תחביריות בזמן הידור בלבד, אינן מיוצגות כעצמים חיים בזיכרון ואינן מסוגלות לקבל הודעות.

18.5 · רמה 3: מערכת עצמים בת 3 רמות (מטה-מחלקה יחידה) דוגמאות: Smalltalk-76, Little Smalltalk

אפיון: המחלקות הן עצמים חיים בזמן ריצה המגיבים להודעות, וכל המחלקות כולן הן מופעים של מטה-מחלקה גנרית יחידה ומשותפת (הנקראת לרוב Class), היורשת מהמחלקה הגנרית "עצם" (Object) ומגדירה את המבנה האופייני של מחלקה (משתני מופע, מצביע למחלקת-על, מילון מתודות) ואת מתודת היצירה המשותפת new.
⚠️ המגבלה המרכזית: מכיוון שכל המחלקות הן מופעים של אותה מטה-מחלקה יחידה (Class), לכל המחלקות יש בדיוק את אותן מתודות מחלקה ואת אותם משתני מחלקה! לא ניתן להגדיר בנאים ייחודיים לכל מחלקה (כמו Point x: 3 y: 4 או Color r:g:b:) מבלי לחשוף אותם לכל שאר המחלקות במערכת!

18.6 · רמה 4: מערכת עצמים בת 4 רמות דוגמאות: שפות LOOPS, ObjVlisp

אפיון: פותרת את מגבלת רמה 3 בכך שהיא מאפשרת להגדיר מטה-מחלקה פרטית לכל מחלקה (או לשתף מטה-מחלקה בין מספר מחלקות), וכך לכל מחלקה יכולים להיות מתודות מחלקה ומשתני מחלקה ייחודיים משלה (ומדיניות יצירת מופעים עצמאית). כל המטה-מחלקות הפרטיות הללו הן מופעים של מטה-מחלקה גנרית משותפת אחת ("מטה-עצם" / "המטה-מחלקה בה' הידיעה"), היורשת מ"עצם".

18.7 · רמה 5: מודל ה-Explicit Metaclass (5 רמות) דוגמאות: Squeak ו-Smalltalk-80

אפיון: לכל מחלקה נוצרת אוטומטית מטה-מחלקה פרטית משלה שמתארת רק אותה, וגרף הירושה של המטה-מחלקות חופף ומקביל לגרף הירושה של המחלקות הרגילות. כל המטה-מחלקות הן מופעים של המחלקה הגנרית Metaclass, שלה עצמה יש מטה-מחלקה משלה (Metaclass class). המודל פותר את בעיית הרגרסיה האינסופית ("מי יצר את המטה-מחלקה?") באמצעות קשר מעגלי סגור בין Metaclass ל-Metaclass class!

עזר גרפי 18.2 • השוואת 5 הרמות של מערכות העצמים (18.3–18.7)

משכפול אב-טיפוס ברמה 1 (Self) ועד למודל 5 הרמות והמעגל הסגור ב-Squeak

Levels 1 to 5 Evolution
רמה 1: Self Prototype-based עצמים בלבד שכפול (Cloning) אין מחלקות כלל רמה 2: Eiffel / ++C מחלקות בזמן הידור מחלקה (לא עצם חי) מופעים בזמן ריצה מחלקה לא מקבלת הודעות רמה 3: Smalltalk-76 מטה-מחלקה יחידה Class (יחידה לכולן) מחלקות כעצמים מופעים סופיים אין בנאים פרטיים למחלקה! רמה 4: ObjVlisp LOOPS · מטה-מחלקות מטה-עצם גנרי יחיד מטה-מחלקה פרטית מחלקות (Classes) מופעים סופיים מתודות מחלקה פרטיות! רמה 5: Squeak Explicit Metaclass 5. Metaclass class 4. Metaclass 3. מטה-מחלקה פרטית 2. מחלקה (Class) 1. מופע סופי היררכיה מקבילה + מעגל סגור!
📚

מיני-סימולציה 18.2: מסווג שלוש שכבות העצמים (דוגמת הספרים והמחזות – סעיף 18.2)

לחץ על כל עצם כדי לראות לאיזו מטה-רמה הוא שייך ומה הוא מסוגל לייצר
⏳
סימולציה אינטראקטיבית גדולה 18.2

מכונת הזמן של הארכיטקטורות: מרמה 1 (Self) ועד רמה 5 (Squeak)

עבור בין 5 הארכיטקטורות ונסה בכל אחת מהן לבצע שלוש משימות הנדסיות: (1) יצירת עצם חדש בזמן ריצה, (2) שליחת הודעה למחלקה עצמה, ו-(3) הגדרת בנאי ייחודי למחלקה (כמו Point x: 10 y: 20):

⚡

הגשר הנרטיבי: הבנו מדוע Squeak זקוקה ל-5 רמות – עכשיו בוא נפרוס את 10 החוקים השולטים במודל הזה!

עכשיו, כשהבנו מדוע מודל 5 הרמות של Squeak ו-Smalltalk-80 נולד, אנחנו מוכנים לצלול אל חוקי הברזל שמנהלים כל אינטראקציה במערכת. בלשונית הבאה נתחיל מחמשת החוקים הבסיסיים (חוקים 1–5), ננתח שורת קוד חיה שיוצרת אליפסה בצבע כחול שקוף (TranslucentColor), ונעקוב צעד-אחר-צעד אחר אלגוריתם איתור המתודה (Method Lookup) במעלה שרשרת הירושה!

חלק VII: מטה-מחלקות • יחידה 18.8–18.9 חוקים 1–5 ומנגנון שליחת ההודעות

מודל העצמים ב-Smalltalk: חמשת החוקים הבסיסיים ואיתור מתודות במעלה ההיררכיה

חמשת חוקי היסוד הראשונים (Rules 1–5), ניתוח דוגמת הקוד של EllipseMorph ו-TranslucentColor, וההבחנה הקריטית בין "קשר מופע" (Instance of – צעד ראשון באיתור) לבין "קשר ירושה" (Superclass – המשך הטיפוס).

🔍
🧠

מודל מנטלי ועיקרון מנחה: צעד אחד על חץ "מופע של", ואז טיפוס על חיצי "ירושה" בלבד!

💡 האנלוגיה המוחשית

כשאתה שולח הודעה לעצם (כמו translucentBlue class), העצם לא מחזיק בתוכו את קוד המתודות. הוא עושה צעד אחד אל המחלקה שלו (TranslucentColor), ומשם מטפס במדרגות הירושה (Color ← Object) עד שהוא מוצא את המתודה!

⚖️ חוק הברזל הפדגוגי

לעולם אל תבלבל בין קשר מופע (Instance of) לבין קשר ירושה (Inherits from): איתור מתודה חוצה קשר מופע פעם אחת בלבד בהתחלה (מהמקבל אל מחלקתו), ומאותו רגע עולה אך ורק בשרשרת הירושה (superclass).

🎯 תובנת המפתח

כאשר המתודה class מאותרת לבסוף במחלקה Object ומורצת, המשתנה הפנימי self שלה עדיין מצביע על המקבל המקורי (translucentBlue), ולכן מוחזרת מחלקתו המדויקת: TranslucentColor!

1. סעיף 18.8: חמשת החוקים הבסיסיים של מודל העצמים (Rules 1–5)

חמשת עמודי התווך הראשונים שעליהם נשענת כל פעולה ב-Squeak

מודל העצמים השלם של Squeak נשלט על ידי עשרה חוקי יסוד מדויקים. חמשת החוקים הראשונים מסכמים את התנהגות העצמים, המחלקות והירושה הרגילה:

Rule 1 Everything is an object

כל דבר במערכת הוא עצם.

Rule 2 Every object is an instance of a class

כל עצם הוא מופע של מחלקה.

Rule 3 Every class has a superclass

לכל מחלקה יש מחלקת-על (למעט שורש העץ ProtoObject).

Rule 4 Everything happens by message sending

כל חישוב מתבצע אך ורק באמצעות שליחת הודעות.

Rule 5 Method lookup follows inheritance

איתור מתודה מתחיל במחלקת המופע ועולה במעלה שרשרת הירושה.

2. הוכחת החוקים בקוד חי: Color, TranslucentColor ו-EllipseMorph

פירוק שורת הקוד של אליפסה בכחול שקוף וזיהוי כל העצמים וההודעות שבה

בוא נבחן סדרת ביטויים ב-Squeak שממחישה כיצד חמשת החוקים האלה פועלים יחד ביצירת צורה גרפית שקופה למחצה:

Color blue                      "מחזיר את העצם המייצג צבע כחול אטום"
Color blue class                --> Color (הצבע הכחול הוא מופע של המחלקה Color)
(Color blue alpha: 0.4) class   --> TranslucentColor (קביעת שקיפות יוצרת מופע של TranslucentColor!)
EllipseMorph new color: (Color blue alpha: 0.4); openInWorld

בוא ננתח בדיוק אילו הודעות נשלחות כאן ולאילו עצמים:

  • ההודעה blue נשלחת אל עצם המחלקה Color ומחזירה מופע של Color.
  • ההודעות alpha: 0.4 ו-class נשלחות אל עצם הצבע: שליחת alpha: 0.4 לצבע הכחול יוצרת ומחזירה עצם חדש (שנקרא לו translucentBlue), שהוא מופע של תת-המחלקה TranslucentColor!
  • מחלקת-העל (superclass) של TranslucentColor היא Color, ומחלקת-העל של Color היא Object (ההודעה superclass נשלחת לעצם המחלקה).
  • ההודעות color: ו-openInWorld נשלחות בשרשור (Cascade עם ;) אל המופע החדש שנוצר מהמחלקה EllipseMorph.

3. סעיף 18.9: כיצד מאותרת המתודה class בעת שליחתה ל-translucentBlue?

מעקב דו-שלבי: קפיצת "מופע של" (קו מקווקו) ואחריה טיפוס בשרשרת "יורשת מ-" (קו רציף)

כאשר אנחנו מבצעים את הביטוי translucentBlue class (כלומר (Color blue alpha: 0.4) class), מתרחש תהליך איתור המתודה (Method Lookup) לפי חוק 5:

  1. מעבר מהעצם למחלקתו (Instance of): המקבל הוא העצם translucentBlue. מנגנון האיתור פונה אל המחלקה שממנה הוא נוצר — TranslucentColor.
  2. חיפוש ב-TranslucentColor: האם המתודה class מוגדרת ב-TranslucentColor? לא!
  3. טיפוס למחלקת-העל Color: האיתור עולה במעלה קשר הירושה אל Color. האם class מוגדרת שם? לא!
  4. טיפוס למחלקת-העל Object: האיתור ממשיך לעלות אל Object. האם המתודה class מוגדרת ב-Object? כן! נמצאה! המתודה מופעלת על המקבל המקורי (self = translucentBlue) ומחזירה את מחלקתו: TranslucentColor.
עזר גרפי 18.3 • נתיב איתור המתודה (Method Lookup – סעיף 18.9)

הבחנה בין קשר מופע (מקווקו) לקשר ירושה (רציף) בשליחת translucentBlue class

Rule 5 Visualization
translucentBlue (alpha = 0.4) מופע של (instance of) TranslucentColor ✗ class לא נמצאה כאן superclass Color ✗ לא נמצאה superclass Object ✓ המתודה class נמצאה! נתיב איתור המתודה (Method Lookup) ➔ מחזיר TranslucentColor
🔬

מיני-סימולציה 18.3: מפרק ההודעות והעצמים בביטוי ה-EllipseMorph

לחץ על כל הודעה בביטוי כדי לראות מי המקבל (Receiver), מי המחלקה ומה מוחזר
🧭
סימולציה אינטראקטיבית גדולה 18.3

סימולטור איתור מתודות חי (Method Lookup) ויצירת EllipseMorph שקוף

שנה את ערך השקיפות (alpha:) כדי ליצור צבע אטום (alpha = 1.0, מופע של Color) או שקוף למחצה (alpha = 0.4, מופע של TranslucentColor), ובצע מעקב צעד-אחר-צעד אחר איתור ההודעה בשרשרת הירושה:

בחר שקיפות (alpha:) עבור האליפסה: alpha: 0.4 (TranslucentColor)
טקסט רקע בעולם ה-Morphic לבדיקת השקיפות של האליפסה
EllipseMorph
מעקב שלבי איתור המתודה (Rule 5):
⚡

הגשר הנרטיבי: הבנו איך מאתרים מתודה שנשלחת למופע רגיל – אבל מה קורה כששולחים הודעה למחלקה עצמה (כמו TranslucentColor blue או TranslucentColor new)?

ראינו שכאשר שולחים הודעה למופע translucentBlue, החיפוש מתחיל במחלקתו TranslucentColor ועולה אל Color ואל Object. אבל מה קורה כשאנחנו שולחים הודעה ישירות לעצם המחלקה TranslucentColor (למשל TranslucentColor blue או TranslucentColor new)? היכן מתחיל החיפוש אז, ואיך היררכיית המטה-מחלקות המקבילה (חוקים 6 ו-7) פותרת את אחת ממלכודות הבחינה המפורסמות ביותר? בוא נעבור ללשונית 4!

חלק VII: מטה-מחלקות • יחידה 18.10–18.11 חוקים 6–7, היררכיה מקבילה ואיתור מתודת new

עקרונות המטה-מחלקות, היררכיה מקבילה (Rule 7) ותהליך איתור המתודה new

6 עובדות הברזל של מטה-מחלקות (Rule 6), ההודעות שמחלקות מקבלות כעצמים, אפקט הראי של ההיררכיה המקבילה (Rule 7), שכתוב מתודות מחלקה (blue), ומלכודת הבחינה הקלאסית: כיצד מאותרת TranslucentColor new ב-Behavior!

🪞
🧠

מודל מנטלי ועיקרון מנחה: אפקט הראי — היררכיית המטה-מחלקות משקפת במדויק את היררכיית המחלקות!

💡 האנלוגיה המוחשית

לכל מחלקה יש "צל" צמוד ואישי משלה — המטה-מחלקה שלה (למשל ל-Color יש את Color class). כשהמחלקה TranslucentColor יורשת מ-Color, גם ה"צל" שלה (TranslucentColor class) יורש אוטומטית מה"צל" של Color (Color class)!

⚖️ חוק הברזל הפדגוגי

הקשר בין מחלקה (TranslucentColor) לבין המטה-מחלקה שלה (TranslucentColor class) הוא קשר של "מופע של" (Instance of) ולא קשר ירושה! מחלקת-העל של TranslucentColor היא Color.

🎯 תובנת המפתח (מלכודת הבחינה!)

כשמבצעים TranslucentColor new, החיפוש לא עובר דרך Color! הוא מתחיל ב-TranslucentColor class, מטפס בשרשרת המטה-מחלקות (Color class ← Object class ← Class ← ClassDescription) ונעצר ב-Behavior!

1. סעיף 18.10: חוק 6 – כל מחלקה היא מופע של מטה-מחלקה (Rule 6)

6 עובדות הברזל של מטה-מחלקות וההודעות שאנחנו יכולים לשלוח למחלקות כעצמים חיים

כעת אנו נכנסים אל חמשת החוקים המשלימים של המודל (חוקים 6–10), העוסקים במטה-מחלקות. חוק 6 קובע: Every class is an instance of a metaclass (כל מחלקה היא מופע של מטה-מחלקה). בכל פעם שאנחנו יוצרים מחלקה חדשה במערכת (למשל Color), נוצרת עבורה אוטומטית מטה-מחלקה פרטית יחידה (Color class), והמחלקה Color היא המופע היחיד שלה.

📌 6 עובדות הברזל שעליך לזכור על מטה-מחלקות:

1. המופעים שלהן הם מחלקות: מטה-מחלקות הן מחלקות לכל דבר, שמופעיהן הם עצמי המחלקות במערכת.
2. נוצרות אוטומטית: אינך יוצר מטה-מחלקה ידנית; היא נוצרת אוטומטית ברגע שאתה מגדיר מחלקה חדשה.
3. מופע יחיד בלבד (Singleton): לכל מטה-מחלקה קיים מופע אחד ויחיד בדיוק — המחלקה שעבורה היא נוצרה!
4. אנונימיות (Implicit): מטה-מחלקות הן חסרות שם עצמאי גלובלי, בעוד שהמופעים שלהן (המחלקות) משמשים כמשתנים גלובליים.
5. גישה באמצעות ההודעה class: ההתייחסות למטה-מחלקה נעשית תמיד דרך המופע היחיד שלה — שליחת Color class מחזירה את המטה-מחלקה של Color.
6. קשר מופע ולא ירושה! הקשר בין TranslucentColor לבין TranslucentColor class הוא "מופע של"; היא אינה תת-מחלקה שלה! מחלקת-העל שלה היא Color.

💬 אילו הודעות ניתן לשלוח למחלקה בהיותה עצם?

  • subclasses – מחזירה מערך של תתי-המחלקות הישירות שלה.
  • allSuperclasses – מחזירה אוסף של כל מחלקות-העל שלה בשרשרת הירושה.
  • instVarNames – מחזירה מערך עם שמות משתני המופע שהוגדרו במחלקה עצמה.
  • allInstVarNames – מחזירה את כל שמות משתני המופע, כולל אלו שהוגדרו במחלקות-העל!

🔎 מה מציג חלון ה-Inspector כשבוחנים עצם ומחלקה?

כאשר אתה פותח את כלי ה-Inspector על עצם (כגון הצבע הכחול Color blue), כותרת חלון ה-Inspector מציגה את שם המחלקה שלו (Color) ולא את שם העצם עצמו, כדי לאשר מאיזה טיפוס הוא נוצר. וכאשר תפתח Inspector על עצם המחלקה Color עצמה, הכותרת תציג את מחלקתה — כלומר Color class!

2. סעיף 18.11: חוק 7 – היררכיית המטה-מחלקות מקבילה להיררכיית המחלקות!

אפקט הראי, ירושת מתודות מחלקה (blue), ומסלול איתור המתודה TranslucentColor new

חוק 7 קובע: The metaclass hierarchy parallels the class hierarchy. היררכיית הירושה של המטה-מחלקות מקבילה ומשתקפת באופן מושלם להיררכיית הירושה של המחלקות הרגילות! כלומר, המטה-מחלקה של מחלקת-העל היא מחלקת-העל של המטה-מחלקה:

TranslucentColor       --inherits--> Color       --inherits--> Object
TranslucentColor class --inherits--> Color class --inherits--> Object class
TranslucentColor class superclass superclass  --> Object class

מהי המשמעות האדירה של חוק 7? המשמעות היא שמתודות מחלקה מורשות בדיוק כמו מתודות מופע! בוא נבחן שני תרחישים מרתקים שמוכיחים זאת:

🔵 תרחיש 1: שליחת TranslucentColor blue ושכתוב (Overriding)

כאשר אנו שולחים את ההודעה blue אל המחלקה TranslucentColor:
1. החיפוש מתחיל במחלקתה של המקבלת — ב-TranslucentColor class.
2. המתודה אינה שם, ולכן החיפוש עולה אל מחלקת-העל שלה — Color class, שם blue מוגדרת ומחזירה כחול רגיל!
💡 שאלה לדיון: כיצד נגרום ל-TranslucentColor blue להחזיר כחול שקוף? פשוט נגדיר (נדרוס / Override) מתודה בשם blue בתוך המטה-מחלקה TranslucentColor class!

🏆 תרחיש 2 (מלכודת הבחינה!): היכן מוגדרת ומאותרת המתודה new?

כאשר מבצעים TranslucentColor new:
1. המקבל הוא עצם המחלקה TranslucentColor.
2. החיפוש מתחיל במחלקתו — ב-TranslucentColor class (ולא ב-Color!).
3. בהיעדר דריסה מקומית, החיפוש עולה בשרשרת המטה-מחלקות: TranslucentColor class ← Color class ← Object class.
4. מ-Object class החיפוש ממשיך אל מחלקת-העל שלה Class ← ClassDescription ← ונעצר ב-Behavior, שבה המתודה new ממומשת בפועל!
5. המתודה new ב-Behavior משתמשת בערך ה-self (שהוא המקבל המקורי TranslucentColor!) ולכן מחזירה מופע חדש של TranslucentColor (ולא של Behavior)!

עזר גרפי 18.4 • אפקט הראי: היררכיה מקבילה ואיתור מתודת new (18.10–18.11)

היררכיית המחלקות (ימין) מול היררכיית המטה-מחלקות המקבילה (שמאל) ומסלול new עד Behavior

Parallel Hierarchies
היררכיית המחלקות (Classes) Object Color TranslucentColor היררכיית המטה-מחלקות המקבילה (Metaclasses) Object class Color class ✓ כאן מוגדרת המתודה blue TranslucentColor class instance of instance of מופע של (לא ירושה!) Class ➔ ClassDescription ➔ Behavior ✓ כאן ממומשת new! קו רציף = ירושה (superclass)   |   קו מקווקו ירוק = קשר מופע (instance of / הודעת class)
🪞

מיני-סימולציה 18.4: משערך הודעות למחלקות ומטה-מחלקות

לחץ על כל ביטוי Smalltalk כדי לראות את תוצאתו ואת ההסבר המלא
🚀
סימולציה אינטראקטיבית גדולה 18.4

מעבדת איתור מתודות במטה-מחלקות: TranslucentColor blue ו-TranslucentColor new

בחר אחד משלושת התרחישים הקלאסיים וצפה במסלול האיתור המדויק שלו על גבי היררכיית המטה-מחלקות (כולל מהו ערך ה-self בכל שלב ואיזה מופע מוחזר בסוף!):

⚡

הגשר הנרטיבי: ראינו ש-Object class יורשת מ-Class, מ-ClassDescription ומ-Behavior – מה תפקידה של כל אחת מהן, ואיך נסגר המעגל של Metaclass?

במסלול האיתור של new גילינו שבקצה עץ המטה-מחלקות נמצאות שלוש מחלקות ליבה מסקרנות: Class, ClassDescription ו-Behavior. מדוע הפרידו המתכננים של Smalltalk את ההתנהגות של מחלקות לשלוש שכבות נפרדות? ואיך חוקים 8, 9 ו-10 סוגרים את הקשר המעגלי של Metaclass ו-Metaclass class? בוא נעבור ללשונית 5!

חלק VII: מטה-מחלקות • יחידה 18.12–18.14 חוקים 8–10 והדיאגרמה הארכיטקטונית השלמה

ירושת הליבה (Behavior, ClassDescription, Class) והמעגל הסגור של Metaclass

פירוק תפקידי שלוש מחלקות הליבה (Rule 8), מדוע כל המטה-מחלקות הן מופעים של Metaclass היורשת מ-ClassDescription (Rule 9), וסגירת הקשר המעגלי בין Metaclass ל-Metaclass class (Rule 10).

♾️
🧠

מודל מנטלי ועיקרון מנחה: כל מטה-מחלקה היא גם "מחלקה" (יורשת מ-Behavior) וגם "עצם" (מופע של Metaclass)!

💡 חוק 8 (קו הירושה הרציף)

מכיוון שמטה-מחלקות הן מחלקות שמייצרות מופעים, כולן יורשות בסופו של דבר (דרך Object class) מ-Class ← ClassDescription ← Behavior ← Object.

⚖️ חוק 9 (קו המופע המקווקו)

מכיוון שכל מטה-מחלקה היא גם עצם, כל המטה-מחלקות כולן (TranslucentColor class, Color class, Object class וכו') הן מופעים של המחלקה Metaclass (שיורשת מ-ClassDescription).

🎯 חוק 10 (סגירת המעגל!)

המחלקה Metaclass היא מופע של המטה-מחלקה שלה Metaclass class, ואילו Metaclass class (בהיותה מטה-מחלקה!) היא מופע של Metaclass. כאן נעצרת הרגרסיה האינסופית!

1. סעיף 18.12: חוק 8 – כל מטה-מחלקה יורשת מ-Class ומ-Behavior

פירוק שלוש שכבות הליבה שמעניקות למחלקות ולמטה-מחלקות את כוחן: Behavior, ClassDescription ו-Class

ראינו קודם שכל מטה-מחלקה (כמו TranslucentColor class או Color class) יורשת במעלה עץ המטה-מחלקות עד שהיא מגיעה אל Object class. אבל ממי יורשת Object class? כאן נכנס לפעולה חוק 8 (Rule 8: Every metaclass inherits from Class and Behavior): בקצה עץ המטה-מחלקות, Object class יורשת מ-Class, אשר יורשת מ-ClassDescription, אשר יורשת מ-Behavior, אשר יורשת מ-Object!

1. Behavior

שורש ההתנהגות ויצירת המופעים

מספקת את המינימום ההכרחי הנדרש למחלקה: הגדרת מבנה המופעים, הידור מתודות והרצתן, קישור להיררכיית הירושה, ומכילה את המתודות הבסיסיות ליצירת עצמים: new, basicNew, new: ו-basicNew:.

2. ClassDescription

ארגון, פרוטוקולים ומעקב שינויים

מחלקה מופשטת המרחיבה את Behavior ביכולות ארגוניות המשמשות את סביבת הפיתוח והדפדפנים: שמות מפורשים למשתני מופע, ארגון מתודות בפרוטוקולים (קטגוריות), הערות תיעוד, מעקב שינויים (Change sets) ושמירה לקובץ (file-in / file-out).
ממנה יורשות שתי מחלקות אחיות: Class ו-Metaclass!

3. Class

מחלקות בעלות שם ומשתני מחלקה

מוסיפה את המאפיינים הייחודיים למחלקות רגילות בעלות שם גלובלי (שאינם קיימים במטה-מחלקות אנונימיות!): שם המחלקה, ניהול משתני מחלקה (classVariables) ומאגרים משותפים (poolDictionaries).

2. סעיפים 18.13–18.14: חוקים 9 ו-10 – הפרדוקס הלוגי וסגירת המעגל של Metaclass

כיצד הקשר המעגלי בין Metaclass ל-Metaclass class בולם את הרגרסיה האינסופית?

עכשיו אנחנו מגיעים אל השיא האינטלקטואלי של הפרק כולו: כל מטה-מחלקה במערכת (כמו TranslucentColor class, Color class, Object class) היא עצם חי בזיכרון. ואם היא עצם, לפי חוק 2 היא חייבת להיות מופע של מחלקה כלשהי! לאיזו מחלקה שייכות כל המטה-מחלקות?

👑 חוק 9 (סעיף 18.13): Every metaclass is an instance of Metaclass

כל המטה-מחלקות במערכת הן מופעים של מחלקה אחת מיוחדת הנקראת Metaclass! וממי יורשת המחלקה Metaclass עצמה? מכיוון שמטה-מחלקות הן אנונימיות (חסרות שם גלובלי), Metaclass אינה צריכה את תכונת השם של Class, ולכן היא יורשת ישירות מ-ClassDescription (כאחות של Class)!

♾️ חוק 10 (סעיף 18.14): The metaclass of Metaclass is an instance of Metaclass

מכיוון ש-Metaclass היא מחלקה, לפי חוק 6 חייבת להיות לה מטה-מחלקה משלה: Metaclass class (היורשת מ-ClassDescription class). אבל של מי מופע היא Metaclass class? בהיותה מטה-מחלקה, לפי חוק 9 היא בעצמה מופע של המחלקה Metaclass!
כאן נסגר המעגל הסופי: Metaclass היא מופע של Metaclass class, ו-Metaclass class היא מופע של Metaclass!

עזר גרפי 18.5 • הדיאגרמה הארכיטקטונית השלמה של Squeak (סעיפים 18.12–18.14)

שילוב חיצי הירושה (רציפים) וחיצי המופעים (מקווקווים) עד למעגל הסגור של Metaclass

Complete Squeak Metamodel
Object Color TranslucentColor Behavior (new) ClassDescription Class Metaclass Object class Color class TranslucentColor class Metaclass class ⬅ חוק 10: מעגל מופעים סגור!
🧱

מיני-סימולציה 18.5: חוקר ארבע מחלקות הליבה של המודל (Behavior, ClassDescription, Class, Metaclass)

לחץ על כל מחלקת ליבה כדי לגלות את תפקידה, מחלקת-העל שלה והמתודות שלה
🕸️
סימולציה אינטראקטיבית גדולה 18.5

מבוך ההיררכיה של Squeak: סינון שכבות ירושה (Inherits From) מול מופעים (Instance Of)

בחר כל צומת בגרף של Squeak או סנן את שכבות החצים (כחול = ירושה superclass, ירוק = מופע class) כדי לראות איך כל צומת מחובר בשני הצירים וכיצד הכל מתכנס אל Object (בירושה) ואל המעגל של Metaclass (במופעים):

לחץ על כל צומת במערכת לניתוח מיידי של שני ציריו:
⚡

הגשר הנרטיבי: סגרנו את המעגל של Metaclass – בוא נסכם את 10 החוקים ו-9 עקרונות המודל ונפתור ביטויי בחינה מורכבים!

כעת כל עשרת החוקים של מודל העצמים ב-Squeak פרוסים לפניך בבהירות מלאה. בלשונית האחרונה והמסכמת של פרק 18 נרכז את רשימת 9 עקרונות הברזל המסכמים של המודל, נתאמן על פיצוח ביטויי השוואה מורכבים של בחינות (כמו a class superclass class == b class class superclass), ונתרגל את כל מושגי הפרק ב-12 כרטיסיות זיכרון תלת-ממדיות!

חלק VII: מטה-מחלקות • יחידה 18.15 סיכום אינטגרטיבי ומילון מושגים אינטראקטיבי

סיכום עקרונות מודל המטה-מחלקות, מנתח ביטויי בחינה וכרטיסיות זיכרון (3D Flashcards)

9 עקרונות הסיכום של מודל המחלקות ב-Smalltalk (סעיף 18.15), מעבדת פתרון ביטויי שרשור לבחינה (כגון a class superclass class == b class class superclass), ו-12 כרטיסיות זיכרון תלת-ממדיות על כל מושגי פרק 18.

🏆
🧠

מודל מנטלי ועיקרון מנחה: 10 חוקי היסוד ו-9 עקרונות המודל יוצרים מערכת עקבית, שלמה וסגורה!

💡 אחידות האיתור (Lookup)

יש רק אלגוריתם איתור מתודות אחד במערכת כולה: בין אם שולחים הודעה למופע רגיל ובין אם שולחים הודעה למחלקה, תמיד מתחילים במחלקה של המקבל ועולים בשרשרת ה-superclass!

⚖️ חוק הזהב לפתרון תרגילי בחינה

בזכות ההיררכיה המקבילה (Rule 7), עבור כל מחלקה C שאינה שורש העץ מתקיים תמיד:
C superclass class == C class superclass!

🎯 סגירת המעגל (Fixed Point)

הקשר ההדדי בין Metaclass ל-Metaclass class מבטיח שכל עצם במערכת הוא מופע של מחלקה ללא שום חריג וללא רגרסיה אינסופית.

📜

סעיף 18.15: תשעת עקרונות היסוד המסכמים של מודל המחלקות והמטה-מחלקות

1. איתור מתודה במעלה הירושה: איתור מתודה מתחיל במחלקת המקבל, ואם אינה נמצאת שם — עולה במעלה היררכיית הירושה.
2. מטה-מחלקה אנונימית ויחידה: לכל מחלקה יש מטה-מחלקה אנונימית הנוצרת אוטומטית בעת יצירתה. המחלקה היא המופע היחיד של המטה-מחלקה שלה.
3. הקבלה מלאה של ההיררכיות: היררכיית ירושת המטה-מחלקות תמיד מקבילה להיררכיית ירושת המחלקות הרגילות.
4. איתור מתודות של מחלקות: זהה לאיתור רגיל, אך מתחיל במטה-מחלקה של המחלקה המקבלת וממשיך מעלה בהיררכיית המטה-מחלקות.
5. ירושה מ-Class ומ-Behavior: מטה-מחלקות הן מחלקות, ולכן כולן יורשות בסופו של דבר מ-Class, מ-ClassDescription ומ-Behavior.
6. מטה-מחלקות כמופעים של Metaclass: מטה-מחלקות הן גם עצמים, ולכן כולן הן מופעים של המחלקה Metaclass.
7. המטה-מחלקה של Metaclass: Metaclass היא מחלקה, ולכן קיימת עבורה מטה-מחלקה (Metaclass class), ו-Metaclass היא המופע היחיד שלה.
8. ירושת Metaclass מ-ClassDescription: Metaclass היא סוג של מחלקה (עבור מחלקות אנונימיות), ולכן יורשת ישירות מ-ClassDescription.
9. הקשר המעגלי הסוגר: Metaclass class היא מטה-מחלקה ולכן היא גם עצם, ובתור שכזו היא מופע של Metaclass — זהו הקשר המעגלי במערכת!
עזר גרפי 18.6 • עשרת חוקי המודל של Smalltalk ו-Squeak במבט-על

חמשת חוקי הבסיס (1–5) לצד חמשת חוקי המטה-מחלקות (6–10)

The 10 Golden Rules
חמשת החוקים הבסיסיים (Rules 1–5) • Rule 1: כל דבר במערכת הוא עצם (Everything is an object) • Rule 2: כל עצם הוא מופע של מחלקה (Instance of a class) • Rule 3: לכל מחלקה יש מחלקת-על (Superclass) • Rule 4: כל חישוב מתבצע בשליחת הודעה (Message sending) • Rule 5: איתור מתודה עולה בשרשרת הירושה (Method lookup) חמשת חוקי המטה-מחלקות (Rules 6–10) • Rule 6: כל מחלקה היא מופע יחיד של מטה-מחלקה אנונימית • Rule 7: היררכיית המטה-מחלקות מקבילה להיררכיית המחלקות • Rule 8: כל מטה-מחלקה יורשת מ-Class ומ-Behavior • Rule 9: כל מטה-מחלקה היא מופע של המחלקה Metaclass • Rule 10: Metaclass class היא בעצמה מופע של Metaclass!
🎓

מיני-סימולציה 18.6: מפצח ביטויי הבחינה בשרשור class ו-superclass

לחץ על כל חידת בחינה כדי לראות את הפתרון השלם צעד אחר צעד
🃏
סימולציה אינטראקטיבית גדולה 18.6

כרטיסיות זיכרון תלת-ממדיות (3D Flashcards) לכל 12 מושגי פרק 18

לחץ על כל כרטיסייה כדי להפוך אותה ולבחון את עצמך על כל אחד מ-12 מושגי היסוד של פרק 18:

נחשפו: 0 / 12
🏆

השלמנו במלואו את פרק 18: המושג "מטה-מחלקה"!

בפרק זה סגרנו את מעגל ההפשטה והעקביות של מודל העצמים ב-Smalltalk וב-Squeak: החל מההבנה שגם מחלקה היא עצם חי בזיכרון (מופע של מטה-מחלקה אנונימית), דרך 5 רמות האבולוציה של מערכות עצמים, ועד ל-10 חוקי היסוד, איתור המתודה new ב-Behavior והמעגל הסגור של Metaclass ו-Metaclass class.

🎯 הטיפ שלי לקראת הבחינה: בכל שאלה שבה מופיע שרשור של class ו-superclass, צייר לעצמך בראש (או על דף הטיוטה) את שני העמודים המקבילים: עמוד המחלקות מימין ועמוד המטה-מחלקות משמאל. זכור ש-class מזיז אותך אופקית (על חץ "מופע של"), ואילו superclass מזיז אותך אנכית למעלה (על חץ "ירושה")!
🕹️

מעבדת חקר אינטראקטיבית במסך מלא

❓

5 שאלות פתוחות מדורגות + 5 שאלות אמריקאיות עם הסברים מלאים לכל יחידה

🏆 השלמת את פרק 18 ואת כל שבעת חלקי המסלול בתכנות מונחה עצמים!

בפרק 18 (חלק VII: מטה-מחלקות) הגענו אל שיא הארכיטקטורה של Smalltalk ו-Squeak וסגרנו את מעגל ההפשטה והעקביות של מודל העצמים: