אבני בניין בהתאמה אישית: מדריך סגנון

במהלך השנים הצוות שלBlockly ו-Blockly Games הלמד לקחים רבים שיכולים להועיל למפתחים חדשים. הרשימה הבאה היא אוסף של טעויות שעשינו או טעויות נפוצות של אחרים.

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

1. לולאות מותנות לעומת לולאות

הבלוקים הקשים ביותר למשתמשים חדשים הם תנאים ולולאות. סביבות רבות שמבוססות על בלוקים מקבצות את שני הבלוקים לאותה קטגוריית Control, ולשני הבלוקים יש צורה זהה ואותו צבע. לעיתים קרובות הדבר מוביל לתסכול מכיוון שמשתמשים חדשים מבלבלים בין שני הבלוקים. ההמלצה שלBlockly היא להעביר תנאים ולולאות לקטגוריות נפרדות של 'לוגי' ו'לולאות', כשכל אחת מהן בצבע אחר. כך אפשר להבהיר שמדובר ברעיונות נפרדים שמתנהגים באופן שונה, למרות שיש להם צורות דומות.

המלצה: כדאי להפריד בין תנאים וללולות.

2. רשימות מבוססות-אחת

מתכנתים מתחילים מגיבים לא טוב כשהם נתקלים ברשימות מבוססות-אפס בפעם הראשונה. לאור זאת, חברתBlockly עוקבת אחר המנהיגים של Lua ו-Lambda Moo על ידי יצירת רשימות ומחרוזות של מחרוזות על בסיס ערך אחד.

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

המלצה: 1 הוא המספר הראשון.

3. קלט של משתמשים

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

המלצה: בחרו שיטת קלט שמתאימה למשתמשים שלכם.

4. תמונות של בלוקים בשידור חי

מסמכי התיעוד של הבלוקים צריכים לכלול תמונות של הבלוקים שאליהם הם מתייחסים. קל ליצור צילומי מסך. אבל אם יש 50 תמונות כאלה, והאפליקציה מתורגם ל-50 שפות, פתאום אחת מהן שומרת 2,500 תמונות סטטיות. לאחר מכן ערכת הצבעים תשתנה, וצריך לעדכן 2,500 תמונות – שוב.

כדי לחלץ את עצמנו מסיוט התחזוקה הזה, החליפו את כל צילומי המסך ב-Blockly Games במופעים שלBlockly שפועלים במצב קריאה בלבד. התוצאה נראית זהה לתמונה, אבל מובטחת שהיא עדכנית. מצב קריאה-בלבד אפשר לנו לשוק הבינלאומי.

המלצה: אם יש תמיכה ביותר משפה אחת, כדאי להשתמש במצב קריאה בלבד.

5. החלק השמאלי האחר שלך

משוב מילדים בארה"ב (אך באופן מעניין לא ממדינות אחרות) גילה בלבול רב בין שמאל לימין. הבעיה נפתרה באמצעות חיצים. אם הכיוון הוא יחסי (לדוגמה, לדמות), סגנון החץ חשוב. חץ ← ישר או חץ פנייה ↱ גורמים לבלבול כאשר הדמות פונה לכיוון ההפוך. האפשרות השימושית ביותר היא חץ ⟳ עגול, גם במקרים שבהם הזווית שפונה קטנה יותר מהחץ.

המלצה: כדאי להוסיף לטקסט סמלים של Unicode כשאפשר.

6. בלוקים ברמה גבוהה

כדאי לנקוט גישה ברמה גבוהה יותר ככל האפשר, גם אם היא מצמצמת את ביצועי הביצוע או הגמישות. למשל, הביטוי הבא ב-Apps Script:

SpreadsheetApp.getActiveSheet().getDataRange().getValues()

במיפוי ביחס של 1:1 שמשמר את כל היכולות הפוטנציאליות, הביטוי שלמעלה ייבנה באמצעות ארבעה בלוקים. אבל המטרה שלBlockly היא להגיע לרמה גבוהה יותר, ולספק בלוק אחד שכולל את הביטוי כולו. המטרה היא לבצע אופטימיזציה לתרחיש של 95%, גם אם זה מקשה על שאר ה-5%. המטרה של blockly היא לא להחליף שפות מבוססות טקסט, אלא לעזור למשתמשים לעבור את עקומת הלמידה הראשונית כדי שיוכלו להשתמש בשפות שמבוססות על טקסט.

המלצה: אל תמירו את כל ה-API באופן עיוור לבלוקים.

7. ערכים אופציונליים להחזרת מוצרים

פונקציות רבות בתכנות מבוסס-טקסט מבצעות פעולה, ולאחר מכן מחזירות ערך. הערך המוחזר הזה לא ניתן לשימוש. דוגמה לכך היא הפונקציה pop() של מקבץ. יכול להיות שתוצג בקשה להבלטת הקהל כדי לקבל ולהסיר את הרכיב האחרון, או רק כדי להסיר את הרכיב האחרון מהערך המוחזר.

var last = stack.pop();  // Get and remove last element.
stack.pop();  // Just remove last element.

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

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

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

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

ד) אכלו את הערך. הגרסה הראשונה של App Inventor יצרה צינור עיבוד נתונים מיוחד שכלל כל ערך המחובר. המשתמשים לא הבינו את המושג, והגרסה השנייה של App Inventor הסירה את הצינור ובמקום זאת המליצה למשתמשים פשוט להקצות את הערך למשתנה מסוג 'לא רלוונטי'.

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

8. אבני בניין בצמיחה

בלוקים מסוימים עשויים לחייב מספר משתנה של ערכי קלט. לדוגמה: בלוק הוספה שמסכם קבוצת מספרים שרירותית, או בלוק if/elseif/else עם קבוצה שרירותית של סעיפים אחרים, או בבונה רשימה עם מספר שרירותי של רכיבים מאותחלים. יש כמה אסטרטגיות, לכל אחת יש יתרונות וחסרונות.

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

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

ב) חלופה היא להרחיב באופן דינמי את הבלוק כך שתמיד יהיה קלט חופשי אחד בסוף. בדומה לכך, הבלוק מוחק את הקלט האחרון אם יש בסוף שני קלטים חופשיים. זוהי הגישה שבה השתמשה הגרסה הראשונה של App Inventor.

משתמשים של App Inventor לא אהבו את הבלוקים שגדלו באופן אוטומטי מכמה סיבות. ראשית, תמיד היה קלט בחינם והתוכנית מעולם לא הייתה 'שלמה'. שנית, הוספת רכיב באמצע המקבץ הייתה מתסכלת, כי היה צורך לנתק את כל הרכיבים שמתחת לעריכה ולחבר אותם מחדש. עם זאת, אם הסדר אינו חשוב, והמשתמשים יכולים להרגיש בנוח עם חורים בתוכנית שלהם, זוהי אפשרות נוחה מאוד.

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

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

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

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

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

9. יצירת קוד נקי

למשתמשים המתקדמים ב-Blockly צריכה להיות אפשרות לראות את הקוד שנוצר (JavaScript, Python, PHP, Lua, Dart וכו') ולזהות מיד את התוכנה שהם כתבו. המשמעות היא שצריך להשקיע מאמץ נוסף כדי שהקוד שנוצר על ידי המחשב יהיה קריא. סוגריים מיותרים, משתנים מספריים, רווחים לבנים מוחצים ותבניות קוד מילוליות מפריעות כולם ליצור קוד אלגנטי. הקוד שאתם יוצרים צריך לכלול תגובות, והוא צריך להתאים למדריכי הסגנון של Google.

המלצה: כדאי להתגאות בקוד שיצרתם. צריך להציג אותו למשתמש.

10. תלות בשפה

אחת מתופעות הלוואי של השאיפה לקוד נקי היא ההתנהגות של blockly מוגדרת ברובה במונחים של אופן הפעולה של השפה המוצלחת. שפת הפלט הנפוצה ביותר היא JavaScript, אבל אם חסימת החסימה תבצע הידור צולב לשפה אחרת, לא נעשה כל ניסיון לא הגיוני לשמר את ההתנהגות המדויקת בשתי השפות. לדוגמה, ב-JavaScript, מחרוזת ריקה היא FALSE ואילו ב-Lua הערך הוא true. הגדרת דפוס התנהגות יחיד להפעלת הקוד של blockly ללא קשר לשפת היעד, תגרום ליצירת קוד שלא ניתן לתחזוקה, שנראה כאילו הוא יצא מהדר של GWT.

המלצה: לחסום אינה שפה. אפשר לשפה הקיימת להשפיע על ההתנהגות.