מה שונה ב רובי 2.1

לפני כחודשים שוחרר רובי 2.1, גרסת preview. הוא מכיל כל מיני שינויים, וגם ייצבו כמה תכונות חדשות אשר נכנסו ל2.0, אבל סומנו כ experimental, או במילים אחרות, לא יציבות.
כאשר אני מדבר כאן על רובי, אני מדבר על cRuby/MRI כלומר הגרסה של יוצר רובי, ולא מימושים אחרים כדוגמת jRuby או Rubinius.

Garbage Collector

בראש ובראשונה, המנוע הוסיף לעצמו GC חדש, אשר נוסף לקיים. התוספת היא סוג של Restricted Generational GC, וקיבל את השם RGenGC.
על רגל אחת (וגם כל הידע שלי בנושא, בעקבות המחקר על הפיטצ'ר), זה אומר כי יש ניסיון למפות לפי "דורות" את האובייקטים השונים. היות וסטטיסטית, מרבית הדברים מהדור האחרון לא יהיו בשימוש יותר מיד עם יציאה מה scope יניחו כי הם יהרסו קודם. אז יוצרים טבלה לפי דורות יצירה, ואלו שללא פניות יותר, יהרסו. זה מקצר מאוד את תהליך ההריסה הרגיל, היות ובשביל לדעת מה להרוס, צריך לעבור על עצים ולהחליט למה אין פניות יותר, אך כאן היחס הוא לינארי, ולכן יהיה מהיר יותר. מדידות שונות הציגו כי הוא מהיר יותר על 2 מילי שניות מהגישה הנוכחית של רובי בקוד יחסית פשוט.
שקפים המסבירים על השינויים והם שייכים לההרצאה הזו:

המודול ObjectSpace קיבל מספר תוספות המאפשרות לבצע איתור אובייקטים לפי שם קובץ, מספר שורה, ומזהה יצירת המתודה והמחלקה.

מחרוזות

הבעיה העיקרית במחרוזות ברובי הוא שהן יכולות להשתנה. כלומר הן מוגדרות כ mutable object, ולכן כל פעם שאצור מחרוזת, גם אם יש כזו, היא תיווצר מחדש, במקום להשתמש במה שכבר קיים (בניגוד לפיתון למשל).
עד היום, היה ניתן ליצור הגדרה של freeze לאובייקט, ואז הוא מוגדר כ immutable, אך בשביל זה, צריך להגדור אותו עבור קבוע.
רובי 2.1 הוסיפה סיומת של "f" למחרוזת רגילה ובכך הופכת אותה לקפואה (כן, זה דוחה):

"foo"f # 1
%q{bar}f # 2

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

בנוסף לכך, רובי 2.1 הוסיפה מתודה חדשה בשם scrub, אשר מעיפה "זבל" ממחרוזת.
הכוונה היא שבמידה ועובדים עם unicode ומקבלים תו לא שלם, היא תדע להעיף אותו מהמחרוזת.
שם המתודה היא scrub.

Decimal Literals

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

0.1 * 3 # 0.30000000000000004

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

0.1r # (1/10)
0.1r * 3 # (3/10)

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

Complex Numbers

בנוסף לסיומת של r, נוספה גם סיומת של i, עבור ייצוג של מספרים מורכבים ומאפשר ליצור מספר מדומה הזהה לשימוש במחלקה Complex.
כלומר:

"42i" == Complex(0, 42)
"3.14i" == Complex(0, 3.14)

יותר מזה, ניתן לשלב בין i וr בייחד:

"42ri" == Complex(0, 42r)
"3.14ri" == Complex(0, 3.14r)

Refinements

ברובי 2.0, נכנסה האפשרות לבצע פעולה הנקראת refinement. הפעולה אומרת שאני יכול לבצע monkey patching לקוד, אבל הוא יתקיים רק בקובץ מסויים בו זה נעשה.
תוסף זה הוגדר כ experimental.
כלומר אם נוסיף ל foo מתודה בשם foo בצורה באה, היא תהיה קיימת רק בקובץ שבה זה הוגדר:

module Foo 
  refine String do 
    def foo 
      self + "foo" 
    end 
   end 
end 

using Foo 
puts "bar".foo

אם תנסו לקרוא לה מחוץ לקובץ, רובי יגיד כי אינו מכיר את foo.
בגרסה 2.1, התרחשו שני דברים, דבר ראשון הוסר דגל ה experimental. דבר שני, ניתן להשתמש במתודה גם בתוך מודול:

module Foo 
  refine String do 
    def foo 
      self + "foo" 
    end 
  end 
end 

module Bar 
  using Foo 
  puts "bar".foo 
end

Required Keyword Arguments

ברובי 2.0, נוספה האפשרות להגדיר פרמטר למתודה אשר יש להזין לו ערך רק לפי שם הפרמטר:

def test(a: 10)
  puts a
end

test        # 10
test(a: 15) # 15
test(5)     # ArgumentError: wrong number of arguments (1 for 0)
test(a: )   # SyntaxError: unexpected ')'

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

def foo(a:) 
  puts a 
end 

foo(a: 20) # 20 
foo        # ArgumentError: missing keyword: a 

ובכך רובי מחייב אותנו לספק ערך לפרמטר.

הגדרת מתודות

עד גרסה 2.0 כולל, הגדרת מתודה ברובי היתה מגדירה ערך חזרה של nil חזרה:

def foo
end

foo # nil

ברובי 2.1, יצירה שכזו תחזיר את שם המתודה:

def foo
end

foo # :foo

החזרת השם במקום ערך nil מאפשרת לעשוות פעולות meta programming בצורה קלה יותר. למשל private יודע לקבל פרמטרים, ובכך אפשר להגדיר אותו כאילו הוא היה מתודה ולא מילה שמורה:

# only foo will be private 
class Foo 
  def foo 
  end 

  private :foo # bar is not affected 

  def bar 
  end 
end

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

# only foo and bar will be private 
class Foo 
   private def foo 
   end 

   private \ 
   def bar 
   end 

   def baz 
   end 
end

ביטים

ברובי 2.1 נכנס לפקודות pack ו unpack אפשרות לעבוד עם מספרים בגודל 64 ביט, כלומר long long, על ידי שימוש בדגלים q! ו Q!. הדגלים יהיו בשימוש רק אם המערכת הפעלה תומכת בגודל הזה.

מתמטיקה

המחלקה Bignum שיפרה את הביצועים שלה בחישובים על ידי מעבר לספרייה GNU GMP.

Symbols

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

StringScanner תומך בתפיסה שמית

רובי מכיל בתוך מנוע ה Regex שלו, אפשרות לספק שם לתוכן שנתפס, למשל "price", ואז בעצם לפנות לשם price בשביל להחזיר את הערך.
ברובי 1.9, נכנס ל stdlib מנוע פיענוח לקסאלי במחרוזות בשם StringScanner.
עד גרסה 2.0 כולל, במידה והיו משתמשים בשם לסוג המידע שנתפס בregex, לא היה ניתן לאחזר אותו, אלא רק את מספר הקבוצה שנתפסה.
החל מרובי 2.1, ניתן להשתמש גם בשם כצורת החזרה של המידע:

require 'strscan' 
s = StringScanner.new("foo") 
s.scan(/(?<bar>.*)/) 
puts s[:bar]

עד גרסה 2.0 כולל, היינו מקבלים הודעת שגיאה:

TypeError: no implicit conversion of Symbol into Integer

מגרסה 2.1 אנחנו נקבל את הערך

foo

ועוד …

הפוסט הפך להיות ארוך מידי, ועדיין לא כיסיתי את כל השינויים והתוספות שנעשו.
אני ממליץ לכם לקרוא את ההכרזה הרשמית (אשר לא מכילה הרבה מידע, אבל כן הרבה קישורים).
בנוסף, אני ממליץ לכם לקרוא עליהם בבלוג של Koichi Sasada, אחד ממפתי ה core של cRuby.
בנוסף יש גם את השקפים הבאים שנכתבו הרבה לפני השחרור הראשון, שיעשו קצת סדר בראש.
בנוסף, בדקו את הרשימה (הלא מלאה) בgit של רובי.

 

כתיבת תגובה

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

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s