Докато си правих проекта стигнах до дилемата дали да пакетирам core функционалстите си в gem или не. Писах директно на fmi@ruby.bg за помощ:
Нужна ми е малко помощ за проекта. Малко се оплетох с това кога правим гем и кога не и всъщност какво точно е гем. Моят проект беше система за състезания по информатика. Въпроса ми в случая е дали core функционалностите са всъщност някаква библиотека/гем? В ядрото ми (ще) се намират всички основни класове необходими за съставянето на едно състезание, но сами по себе си там няма импелементирана никаква бизнес логика. Също така, ако искам, ползвайки класовете в кора, лесно мога да си дефинирам нови типове задачи/състезания/начини на оценяване или компилатори на решения, които след това да миксирам някак си с готовите в ядрото и да създам нов тип състезание. Всичко това аз си го представям като библиотека т.е. гем? Когато след това стигна до имплементиране на самото приложение require-вам библиотеката и просто навързвам класовете.
И получих следния отговор от Митьо:
Да направиш gem не е задължително. Самото понятие "gem" аз лично свързвам с определен начин на пакетиране и разпространяване на обща функционалност в Ruby (библиотека). Технически погледнато, един gem е просто един tar (архив) на една определена директорийна структура, следваща дадена конвенция, плюс един файл, описващ съдържанието на библиотеката по предварително зададена схема. Тази техническа особеност на пакетиране на споделена функционалност има единствената цел да улесни споделянето на функционалност в Ruby-общността. В случая на проектите за курса, обаче, формалното пакетиране на функционалност в gem изобщо не е необходимо, даже попада в графата ненужен overhead.
Причината да говоря за "gem"-ове е за да ви накарам да си наложите категорични граници между "основна" функционалност и "периферна" такава. Ако исках от вас да сложите основната си функционалност в gem, който в последствие да използвате в "интерфейса" си, всеки, ще или не ще, трябваше да раздели нещата някак на "основна" и "периферна" функционалност. Сам разбираш, че да правиш gem не е задължително условие, за да постигнеш тази цел. Може да събереш "основната" си логика в top-level папка "programming_competition_manager", например (ако така ти се казва проекта) и да си ползваш класове от там в "интерфейса" или "периферията", с обикновен require (може да ти се наложи да си модифицираш сам load path-а в нещото, което require-ва части от "основната" логика).
Това, което ти си написал, звучи разумно. Какво точно да вкараш в "основната" функционалност и какво не, си решаваш ти. Може да нямаш една основна функционалност, може да имаш няколко модула и адаптера, които да сглабяш, за да получиш една система за състезания от определен тип. Например, "основната" логика, даваща структура на нещата, плюс "адаптер" за определен тип състезание, плюс определен тип оценчик, плюс адаптер за опрделен тип състезателна динамика (например, да има етап, в който виждаш решения на други хора и пишеш тест, на който смяташ, че ще fail-нат…). Всичко може да е много модулно. Това не е лошо. Не е задължително всяко нещо да е отделен gem. Достатъчно е да има наложени ясни граници между компонентите.
Дано бъде полезно и на някой друг, който е бил в подобна ситуация.