שלום אורח התחבר

היום למדתי: הפונקציה gem ב ruby

נושאים:יומי

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

1בואו נתקין שתי גירסאות של אותו ג'ם

בשביל הדוגמא נתקין שתי גירסאות של ריילס באמצעות הפקודה gem:

$ gem install rails-6.0.0
$ gem install rails-5.2.3

שתי הגירסאות מותקנות לי עכשיו על המכונה ואני יכול לראות את זה באמצעות הפקודה gem info באופן הבא:

$ gem info rails

*** LOCAL GEMS ***

rails (6.0.0, 5.2.3)
    Author: David Heinemeier Hansson
    Homepage: https://rubyonrails.org
    License: MIT
    Installed at (6.0.0): /Users/ynonperek/.rvm/gems/ruby-2.6.3
                 (5.2.3): /Users/ynonperek/.rvm/gems/ruby-2.6.3

    Full-stack web application framework.

אנחנו רואים ב info שאני משתמש ב rvm וששתי הג'מים מותקנות באותה תיקיית רובי. נסתכל בתיקיה כדי לראות את שתי הגירסאות:

$ $ ls -1 -d /Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/*rails*
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/coffee-rails-4.2.2
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/rails-5.2.3
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/rails-6.0.0
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/rails-controller-testing-1.0.4
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/rails-dom-testing-2.0.3
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/rails-html-sanitizer-1.0.4
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/rails-html-sanitizer-1.2.0
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/sass-rails-5.0.7
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/sass-rails-5.1.0
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/sprockets-rails-3.2.1

2איך טוענים את הגירסא החדשה ביותר

באופן רגיל הפקודה require תטען את הגירסא החדשה ביותר של הג'ם שהיא מוצאת:

> require 'rails'
 => true 

> Rails.version
 => "6.0.0"

3איך טוענים גירסא ישנה יותר

עם הפקודה gem אני יכול לטעון גירסאות ישנות יותר של הג'ם:

> gem 'rails', '5.2.3'
 => true 

> require 'rails'
 => true 

> Rails.version
 => "5.2.3"

4גם ריילס משתמש בטריק הזה

ומסתבר שגם ריילס עצמה משתמשת בטריק הזה. קובץ ההרצה rails שיוצר תבנית פרויקט כולל את הקוד הבא:

version = ">= 0.a"

str = ARGV.first
if str
  str = str.b[/\A_(.*)_\z/, 1]
  if str and Gem::Version.correct?(str)
    version = str
    ARGV.shift
  end
end

gem "railties", version

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

$ rails _5.2.3_ --version
Rails 5.2.3

$ rails _6.0.0_ --version
Rails 6.0.0

5באנדלר

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

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

מעדיפים לקרוא מהטלגרם? בקרו אותנו ב:@tocodeil

או הזינו את כתובת המייל וקבלו את הפוסט היומי בכל בוקר אליכם לתיבה:


נהניתם מהפוסט? מוזמנים לשתף ולהגיב