תוסף Outline לקובצי JavaScript ב-Visual Studio 2005

שייך לקטגוריות .NET, JavaScript

מיקרוסופט שכחו את מתכנתי הקליינט סייד הכבדים ב-visual studio ולא הוסיפו את האופציה של collapse ו-expand לפונקציות בקובצי javascript.

מצאתי add-in (אחרי חיפוש קדחתני) חביב ל-visual studio 2005

הורדה – SmartOutline – Javascript Outline for Visual Studio 2005

(לא בדקתי על visual studio 2008, אם זה עובד אשמח לשמוע בתגובות ולעדכן)

מסנן Google Reader

שייך לקטגוריות Greasemonkey
Donations are appreciated :)

** עדכון — הסקריפט מתעדכן לעיתים, אפשר להוריד את הגרסה החדשה ביותר מאתר userscripts, בעמוד google reader filter **

אז אחרי שהבנתי שאני רשום לכ-100 feeds בקורא ה-RSS של גוגל ומבזבז את רוב זמן המסך שלי באובססיביות להשאיר את הרידר ריק (Mark all as read, מישהו?), חשתי בצורך עז לגרום לו שלא להציג לי מה שאני לא רוצה.
אז בלהט הרגע כתבתי סקריפט GreaseMonkey לשימוש אישי, שיודע לנהל מילים לסינון ומילים להבלטה (יותר נכון ביטויי Regex ולא מחרוזות רגילות).

אז מה יש לנו שם?

  • כפתור Filter Settings
  • רשימת ביטויי Regex לסינון ורשימת ביטויי Regex להבלטה

ומה אין (עדיין)?

  • העלמת כפילויות
  • פילטור לפיד או קטגוריה ספציפיים

הוראות שימוש

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

דוגמה לביטויים (שימו לב – ישנו שימוש ב-Regex):

java ?script
css
^free
windows (mobile|media|server)

הורדת Google Reader Filter

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

#C: טיפוסים גנריים (Generic Types) וממשקים (Interfaces)

שייך לקטגוריות .NET, C#

נניח שיש לנו את המחלקה הבאה:

public class ItemCollection<T> : List<T> {
	public ItemCollection<T> Load() {
		// load process here...
		return this;
	}
	public ItemCollection<T> Attach(T item) {
		base.Add(item);
		return this;
	}
	public ItemCollection<T> Clone() {
		ItemCollection<T> cloned=new ItemCollection<T>();
		// clone logic here...
		return cloned;
	}
}

והתוכנית הבאה:

public class Program {
	public static void Main(string[] args) {
		ItemCollection<int> intCollection=new ItemCollection<int>();
		intCollection.Attach(1).Load();
	}
}

ItemCollection היא מחלקה שיורשת מ- List<T> ומוסיפה לה כמה מתודות. שימו לב שגם היא מקבלת T כ-type parameter ומעבירה אותו ל-List עצמו, כלומר תינתן לנו האופציה ליצור מופע עם כל טיפוס כפרמטר, ובתוך המחלקה עצמה נמשיך להתייחס אליו כאילו הוא T.

דבר נוסף, המתודות מחזירות את האובייקט עצמו לשם מימוש fluent interface (בקצרה – החזרת האובייקט מהמתודות שלו כדי שנוכל "לשרשר" מתודות במקום לכתוב את שם האובייקט בכל הפעלה של מתודה).

בתוכנית, יצרנו מופע של ItemCollection מסוג int, הפעלנו עליו את המתודה Attach שבמחלקה עצמה מקבלת T אך למופע שלנו ה-T ייחשב כ-int, עם הפרמטר 1. המתודה Attach החזירה את האובייקט עצמו ועכשיו אנחנו יכולים להפעיל עליו עוד מתודות, כמו Load.

ועכשיו, נניח שיש לנו עוד מחלקת עזר שמקבלת ItemCollection כזה ומוסיפה לו ערך.

public class Helper {
	public void AddToItemCollection(ItemCollection<int> collection,int item) {
		collection.Attach(item);
	}
}

ועכשיו נוכל להעביר לה כפרמטר את האוסף ומספר ולהוסיף לו אותו

Helper.AddToItemCollection(intCollection,2);

אחלה! רק חבל שזה מתאים רק ל ItemCollection<int> . אם יהיה לנו ItemCollection<string>, נאלץ לכתוב מתודה נוספת. אז אנחנו יכולים להפוך את המתודה הזו לגנרית אף היא:

	public static void AddToItemCollection<T>(ItemCollection<T> collection,T item) {
		collection.Attach(item);
	}

ולהוסיף לכל סוג של ItemCollection

		ItemCollection<string> stringCollection=new ItemCollection<string>();
		Helper.AddToItemCollection<string>(stringCollection,"hello");

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

אהה! נממש interface עם המתודות האלה, מה כבר יכולה להיות הבעיה…

public interface IItemCollection {

}

ופה ניתקע. כאן המוח שלנו יתחיל להיכנס ללולאה אינסופית. אני רוצה להגדיר את המתודה Load, מה לעזאזל ערך ההחזרה שלה? נו בוודאי, ItemCollection<… אבל איזה T? אולי נעשה את הממשק גם הוא גנרי? יאללה, רק שלא נרוויח מזה מאום, כי גם כשנרצה להעביר את הממשק כפרמטר הטיפוס שלו יצטרך להכיל את פרמטר הטיפוס או לחילופין להיות גנרי. תסכול מס' 2 :-S.

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

public interface IItemCollection {
	IItemCollection Load();
	IItemCollection Attach(object item);
	IItemCollection Clone();
}

אם המחלקה שלנו תממש את הממשק הזה המתודות שלה יוכלו להחזיר את הממשק עצמו, מתודות שמתייחסות לטיפוס T יועברו כ-object ויעברו פעולת casting קטנה.

public class ItemCollection<T> : List<T>,IItemCollection {
	public IItemCollection Load() {
		// load process here...
		return this;
	}
	public IItemCollection Attach(object item) {
		base.Add((T)item);
		return this;
	}
	public IItemCollection Clone() {
		ItemCollection<T> cloned=new ItemCollection<T>();
		// clone logic here...
		return cloned;
	}
}

עכשיו זה באמת טוב. מימשנו את הממשק, T הופך ל-object והרבה קאסטים גועליים רצים לנו בתוך הלוגיקה. תסכול מס' 3 :-S.

Explicit implementation to the rescue

למה שלא נמשיך להתעקש? בסוף תמיד נגיע למחוז חפצנו. בדוט נט אפשר להגדיר explicit implementation על interface, מה שנותן לנו את האופציה אכן להגדיר את המימוש למתודה אבל רק כאשר המחלקה שלנו מזוהה כאותו ממשק. נקפוץ לקוד:

public class ItemCollection<T> : List<T>,IItemCollection {
	public ItemCollection<T> Load() {
		// load process here...
		return this;
	}
	public ItemCollection<T> Attach(T item) {
		base.Add(item);
		return this;
	}
	public ItemCollection<T> Clone() {
		ItemCollection<T> cloned=new ItemCollection<T>();
		// clone logic here...
		return cloned;
	}

	IItemCollection IItemCollection.Load() {
		return Load();
	}
	IItemCollection IItemCollection.Attach(object item) {
		return Attach((T)item);
	}
	IItemCollection IItemCollection.Clone() {
		return Clone();
	}
}

כעת, המחלקה שלנו כוללת שני מימושים למתודות. ממשקים מחייבים הגדרה אחת של מתודה עם חתימה ספציפית. המימוש של Load שתופס עבור ה-interface הינו המימוש המחזיר IItemCollection. שימו לב לנוכחות ה IItemCollection+נקודה לפני המילה Load – זה אומר שזה המימוש של Load שאותו ממשק דורש. למימוש השני אין קשר לממשק, והוא לא מתנגש עם הממשק. מעתה נוכל להתייחס ל- IItemCollection<> גם כממשק ולהעביר אותו למתודות ללא בעיה.

קוד מתוך התוכנית

		IItemCollection doubleCollection=new ItemCollection<double>();
		Helper.AddToItemCollection(doubleCollection,3.4);
		Logger.Dump(doubleCollection);

המתודה מתוך ה-Helper

	public static void AddToItemCollection(IItemCollection collection,object item) {
		collection.Attach(item);
	}

דוגמה נוספת

public interface IFirst {
	IFirst A();
}
public interface ISecond {
	ISecond A();
}

public class Class : IFirst,ISecond {
	IFirst IFirst.A() {
		Logger.Write("IFirst.A");
		return this;
	}
	ISecond ISecond.A() {
		Logger.Write("ISecond.A");
		return this;
	}
}

public class Helper {
	public static void PrintFirstA(IFirst first) {
		first.A();
	}
	public static void PrintSecondA(ISecond second) {
		second.A();
	}
}

קוד מתוך התוכנית:

		Class c=new Class();
		Helper.PrintFirstA(c);
		Helper.PrintSecondA(c);
		((IFirst)c).A();

ידפיס על המסך

IFirst.A
ISecond.A
IFirst.A

שימו לב שאין מימוש public ל-A אלא מימוש explicit של interface. כל interface מכיל את המתודה A ו-Class נותן מימוש אחר לכל ממשק, כך שכשנתייחס למחלקה כ-IFirst היא תפעיל את IFirst.A וכנ"ל לגבי ISecond.

נפטרים מה-PostBack/ViewState

שייך לקטגוריות ASP.NET

הצוות של סקוט גו(ת'רי) מכפר על עוונותיהם של צוות הפיתוח המקורי של asp.net ושוקד על מנגנון חדש שיחליף את ה-web forms.
המנגנון מבוסס על ה-MVC (Model View Controller) design pattern. החבר'ה נפטרו מ-viewstate/postback, יש עבודה פנימית עם המון design patterns ושיטות שונות (TDD, IoC). הרבה מחלקות מיוצגות עכשיו בעזרת interfaceים, שום דבר לא sealed, כתיבה בשפות דינמיות (כמו Ruby) והכל הרבה יותר נשלט.

סקוט עצמו הכריז בכנס ALT.NET על הפרוייקט, וככל הנראה הוא צפוי לצאת שנה הבאה אחרי Visual Studio 2008 (מדברים על CTP לקראת סוף השנה).

הידיעה המלאה

הבלוג של סקוט גו
MonoRail – ספריית MVC קיימת ל-ASP.NET (לראות את ה-getting started, להתאהב, ולקוות ש-microsoft יוציאו מוצר שלם וטוב יותר כמו שהם יודעים לעשות)



קטגוריות

חיפוש

עיקבו אחרי (אקספרימנטלי!)