לוגו אתר Fresh          
 
 
  אפשרות תפריט  ראשי     אפשרות תפריט  צ'אט     אפשרות תפריט  מבזקים     אפשרות תפריט  צור קשר     חץ שמאלה ‎print ‎"Hello World!"; if‎ ‎not rules.‎know ‎then rules.‎read(); חץ ימינה  

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



  #1  
ישן 08-04-2012, 17:12
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
מה הקוד הבא ידפיס? (ו-Principle of Least Surprise)

נתחיל ממשהו פשוט. מה ידפיס קוד C#‎ הבא?
קוד:
struct Helper { private int x; public int f() { this.x = this.x + 1; return this.x; } } class Test { public Helper h = new Helper(); static void Main(string[] args) { Test t = new Test(); System.Console.WriteLine(t.h.f()); System.Console.WriteLine(t.h.f()); System.Console.WriteLine(t.h.f()); } }
ואם נשתמש ב-class במקום ב-struct, מה ידפיס הקוד הבא?
קוד:
class Helper { private int x; public int f() { this.x = this.x + 1; return this.x; } } class Test { public Helper h = new Helper(); static void Main(string[] args) { Test t = new Test(); System.Console.WriteLine(t.h.f()); System.Console.WriteLine(t.h.f()); System.Console.WriteLine(t.h.f()); } }
ואם במקרה המשתנה h יהיה readonly. מה ידפיס הקוד הבא?
קוד:
class Helper { private int x; public int f() { this.x = this.x + 1; return this.x; } } class Test { public readonly Helper h = new Helper(); static void Main(string[] args) { Test t = new Test(); System.Console.WriteLine(t.h.f()); System.Console.WriteLine(t.h.f()); System.Console.WriteLine(t.h.f()); } }
ואם עכשיו נחזיר את Helper להיות struct במקום class, מה ידפיס הקוד הבא?
קוד:
struct Helper { private int x; public int f() { this.x = this.x + 1; return this.x; } } class Test { public readonly Helper h = new Helper(); static void Main(string[] args) { Test t = new Test(); System.Console.WriteLine(t.h.f()); System.Console.WriteLine(t.h.f()); System.Console.WriteLine(t.h.f()); } }
כמובן שהחוכמה היא לענות על זה בלי לחפש בגוגל ובלי לקמפל. מצד שני, אין פרסים, כך שגם אם תרמו זה לא יעזור לכם.
(סימנתי באדום מודגש את השינוי בכל קטע קוד לעומת הקטע שמעליו.)
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #5  
ישן 08-04-2012, 23:06
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
בתגובה להודעה מספר 4 שנכתבה על ידי Idjo שמתחילה ב "אני אנסה את מזלי. קטעים 2,3..."

ציטוט:
במקור נכתב על ידי Idjo
אני אנסה את מזלי.
קטעים 2,3 ידפיסו 1,2,3 כי אני לא רואה סיבה אחרת. readonly עבור class לא מדבר על ה-instance אלא על ה-reference.
כן.

ציטוט:
במקור נכתב על ידי Idjo
בקטע 4, מכיוון שמדובר ב-value type, ה-readonly אמור למנוע שינוי של המשתנה. לכן נראה לי שיודפס 1,1,1 ובעצם המתודה מבצעת את פעולתה על עותק אחר של המשתנה.
אתה בטוח שזה יתקמפל? אם לדוגמה Helper.x היה public, והיינו מנסים לעשות t.h.x=t.h.x+1 זה היה מתקמפל?

ציטוט:
במקור נכתב על ידי Idjo
בקטע 1 אני מתלבט. ייתכן כי המתודה מבצעת את פעולתה על עותק של המשתנה וייתכן כי היא מבצעת אותו על המשתנה עצמו כי אפשר במקרה זה. אני אהמר שיודפס 1,2,3 כי הפוסט אמור להפתיע.
לא חשבתי על זה שהסדר שבו אני שואל יפריע ככה. טעות שלי.
מה הטיעון בעד יצירת עותק ומה הטיעון בעד גישה ישירה שיש לך?
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #6  
ישן 08-04-2012, 23:46
צלמית המשתמש של Idjo
  Idjo Idjo אינו מחובר  
 
חבר מתאריך: 05.05.02
הודעות: 6,840
בתגובה להודעה מספר 5 שנכתבה על ידי פסטן שמתחילה ב "[QUOTE=Idjo]אני אנסה את..."

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

לגבי הקטע הראשון.
בעד שזה ייצור עותק: קריאה למתודה של class\struct היא בעצם כמו קריאה לפונקציה רגילה כאשר אחד הפרמטרים הוא ה-this. ההתנהגות של העברת פרמטר היא by value אז למה שזה יהיה שונה במקרה שלנו?
בעד שזה ישנה את המשתנה המקורי: זה בד"כ מה שבפועל רוצים. אין כל כך סיבה לשנות רק עותק של המשתנה שיעלם בתום המתודה.

נערך לאחרונה ע"י Idjo בתאריך 08-04-2012 בשעה 23:49.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #7  
ישן 09-04-2012, 00:59
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
בתגובה להודעה מספר 6 שנכתבה על ידי Idjo שמתחילה ב "לגבי הקטע הרביעי. אני די סגור..."

ציטוט:
במקור נכתב על ידי Idjo
לגבי הקטע הרביעי.
אני די סגור שזה יתקמפל. תחשוב על ההפרדה שיש כאן.
ה-struct אמור להתקמפל כי הוא לא "יודע" כלום על ה-readonly.
הקריאה למתודה ממשתנה שהוא readonly אמורה להתקמפל כי ה-class לא "יודע" שזו מתודה המשנה את המשתנה.
עריכה: שכחתי לציין שהדבר השני שאמרת כנראה לא יתקמפל. ההבדל הוא עוד פעם ב"ידיעה". במקרה השני אנו יודעים בבירור שהקוד לא בסדר בעוד שבמקרה הראשון ייתכן כי המתודה לא משנה את המשתנה.
זה נכון שהוא "לא יודע" מה f()‎ עושה, אבל זה הוא יכל לדעת. הם בחרו שלא לדעת. הרי מי שמקמפל את Helper יודע מה עושה כל מתודה שהוא מקמפל. הוא יכול לסמן חלק מהמתודות כ"ניתנות לקריאה על readonly" וחלק כ"לא ניתנות לקריאה על readonly" (או בקיצור mutator). במציאות אתה צודק ובחרו לוותר על הידע הזה, ואז להסתבך במקום אחר.

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

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #9  
ישן 09-04-2012, 14:25
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
בתגובה להודעה מספר 8 שנכתבה על ידי Idjo שמתחילה ב "אם כך הגענו לנקודה שבה זה..."

זה תמיד עניין של טעם.

אפילו עקרונות מוסכמים יחסית לעיצוב שפות תכנות ניתנים לפרשנויות כל-כך שונות, שאי-אפשר 'להוכיח' ששפת תכנות אחת עומדת בהם טוב יותר מאחרת. רשימה קריטריונים לדוגמה: http://www.lshift.net/blog/2006/06/...sign-principles

למרות זאת, אני יכול לחשוב על כמה גישות הגיוניות:

  • גישה אחת היא גישה של const-correctness בסגנון C++‎:
אם אובייקט מוגדר כבלתי-ניתן-לשינוי (ב-C++‎‏ - const), ניתן לבצע עליו אך ורק פעולות שאינן משנות את מצבו. (†‌‏) הקומפיילר דואג לזה באחת משתי דרכים:

  1. ב-C++‎ (ובדרך שהצעתי למעלה) הקומפיילר מרשה לך לקרוא ל-mutators רק אם האובייקט שאתה משתמש בו ניתן-לשינוי. כל פעולה על האובייקט מסומנת על-ידי הכותב על-ידי 'mutator bit' והקומפיילר אוכף את זה שלא תוכל לסמן מתודה של מחלקה ככזו שלא משנה את האובייקט, אם אתה כן מנסה לשנות אותו.
  2. הדרך השנייה היא לאכוף את זה בזמן ריצה - אם אתה מנסה לשנות אובייקט שאסור לשנות, אתה חוטף exception.
  • גישה אחרת היא להפוך את כל האובייקטים ל-immutables
זה לדוגמה מה שקורה בשפות פונקציונאליות.
אפשר להשתמש בגישה הזו גם בשפות שאנחנו מדברים עליהן. בגדול, אף פעם לא משנים כלום - תמיד יוצרים אובייקט חדש שהוא f(x)‎, כש-f היא הטרנספורמציה שאנחנו רוצים לבצע (לדוגמה: מיון, שינוי case של טקסט, וכו').
כאן אנחנו משתמשים באף לא אחת מהגישות האלה. אין שום אכיפה של const-correctness. אפשר לעשות אובייקטים שהם לא immutables, אבל האובייקטים האלה מתנהגים בצורה מוזרה כי אתה מקבל 'חצי הגנה'.


(†‌‏) או פעולות ששומרות על אינווריאנטים מסוימים. לדוגמה, ב-C++‎ אפשר להגדיר שדה של מחלקה כ-mutable, ואז מותר למתודה שנחשבת const לשנות אותו (כשהיא נקראת על אוביקט const-י!), כי הגדרנו במפורש שהשדה הזה איננו חלק מהאינווריאנטים של האובייקט, אפילו כשהוא נחשב const.
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #11  
ישן 10-04-2012, 00:40
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
בתגובה להודעה מספר 10 שנכתבה על ידי Idjo שמתחילה ב "אוקי, די שכנעת אותי שבחרו כאן..."

ציטוט:
במקור נכתב על ידי Idjo
אוקי, די שכנעת אותי שבחרו כאן חצי פתרון.

ציטוט:
במקור נכתב על ידי Idjo
באופן כללי, struct זה עניין בעייתי לדעתי. כדי לחסוך הרבה מהסיבוכים של c++, החליטו (בחוכמה לטעמי) שהמחלקות ב-java ו-c# יהיו reference type. אבל ב-c# כן הכניסו value types מ"הדלת האחורית" ויש לזה את המחיר של התנהגויות לא צפויות. החל מהעובדה הפשוטה שהשימוש ב-struct נראה בקוד אותו דבר כמו שימוש ב-class אבל לא מתנהג כמותו.
טוב, יש לזה מטרות. סעיף 1.7 של ה-C# 4.0 Spcifications, נותן דוגמה לזה. אני כן מסכים שהדרך שבה זה נמצא בשפה מרגישה 'לא טבעית': כל value type יורש מטיפוס אנונימי סודי שיורש מ-System.ValueType, אבל System.ValueType בעצמו הוא reference type, וכל מיני זוועות כאלה.
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

כלי אשכול חפש באשכול זה
חפש באשכול זה:

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

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

קוד vB פעיל
קוד [IMG] פעיל
קוד HTML כבוי
מעבר לפורום



כל הזמנים המוצגים בדף זה הם לפי איזור זמן GMT +2. השעה כעת היא 09:59

הדף נוצר ב 0.06 שניות עם 10 שאילתות

הפורום מבוסס על vBulletin, גירסא 3.0.6
כל הזכויות לתוכנת הפורומים שמורות © 2024 - 2000 לחברת Jelsoft Enterprises.
כל הזכויות שמורות ל Fresh.co.il ©

צור קשר | תקנון האתר