Jak najlepiej zmodyfikować gema?

Znalazłem gema do modyfikacji adresów url (route_translator). Jednak z mojego punktu widzenia posiada on jedną wadę, nie pokazuje defaultowego języka w URLu. Wiem w którym miejscu trzeba to w gemie zmienić, żeby defaultowy język się pokazał, ale gem instalowany jest ogólnie w systemie, a ponieważ chce zmodyfikować gema to chyba lepiej zainstalować go jako plugin w aplikacji.
Po drugie nie chciałbym modyfikować pliku gema w systemie, bo na serwerze produkcyjnym, znowu trzeba będzie zmodyfikować tego gema, a taka operacja raczej nie jest prawidłowa, w ogólności.

Tylko mam problem jak zainstalować tego gema jako plugin, jak wpisuje

rails plugin install route_translator

To otrzymuje taki komunikat błędu:

Plugin not found: ["route_translator"]

Nie jestem pewien, czy jak kody przekopiuje po prostu od tak do aplikacji to czy będzie to działać.

Fork na github, zmieniasz, instalujesz, albo sciagasz, bundlerem podgladasz, zmieniasz, uzywasz, mozesz poszukac recznie gemu jak nie uzywasz bundlera

Jeżeli repo gita jest na githubie to najprosciej jest zrobic tak:

  1. Forkujesz repo na githubie
  2. Robisz swoje poprawki
  3. Wrzucasz poprawki do swojego forka
  4. Edytujesz Gemfile w np taki sposób:
gem "route_translator", :git => "git://github.com/wafcio/route_translator.git"

Ścieżka git do repo powinna byc dostepna na githubie.
5. bundle install

Wówczas aplikacja pobierze zmieniony gem z Twojego forka.

Ok, ale jak nie chciałbym, żeby ta zmiana została upubliczniona ? Jak zwykle wszystko obija się o politykę. A ukryte konta na githubie są płatne, więc najlapiej jakaś alternatywa omijająca githuba.

EDYCJA:
Znalazłem takie rozwiązanie.

W katalogu config/initializers umieszczam plik, który wygląda mniej więcej tak:

RouteTranslator::Translator.module_eval do ... end
I to poprawia działanie gema, tylko pytanie czy ten sposób zmiany kodu gema jest odpowiedni ?

Jeśli chcesz może to być lokalne repo gita. Np u ciebie na serwerze. No ale wcale nie musi być to w cale za pomocą git. Możesz gem gotowy wyedytować u siebie lokalnie. Łatwo tylko coś takiego nadpisać. ;]

A sposób dobry jak każdy inny. Czemu nie po to są initializery by swoje opcję dodać

@wafcio: czemu po prostu nie nadpiszesz interesującej Cie metody/ustawienia w swojej aplikacji?

Nie bedziesz grzebal w gemie, bedzie to przenośne…
Same pozytywy :wink:

[quote=leszek.kalwa]@wafcio: czemu po prostu nie nadpiszesz interesującej Cie metody/ustawienia w swojej aplikacji?
Nie bedziesz grzebal w gemie, bedzie to przenośne…
Same pozytywy ;)[/quote]
No chyba bardziej przenośne będzie, jeśli będzie dodane w Gemie, niż w kodzie aplikacji…

Zwłaszcza jak postanowisz upgrade’ować gema

Nikt nie każe Ci używać Githuba - jeśli nie chcesz płacić za prywatne repozytoria na GH, to postaw własne na swoim serwerze.

Możliwość dodania zależności w Bundlerze do własnej wersji biblioteki trzymanej w Gicie, to jest moim zdaniem jedna z killing feature Bundlera. W Rubim, jeśli chcesz spatchować bibliotekę, to po prostu stawiasz własne repozytorium Gita i w nim trzymasz te zmiana. Możesz również wysłać je do osoby, który utrzymuje bibliotekę, ale póki zmiany nie zostaną wprowadzone, bez przeszkód możesz używać swojej wersji.

Testowałem podobny scenariusz w Javie (korzystając z Mavena do zarządzania zależnościami) i jest to tragicznie gorsze. Musisz postawić własne repozytorium Mavena, musisz do niego deployować zmodyfikowane wersji biblioteki no i upewnić się, że mimo wszystko wersja oryginalna nie przysłoni Twojej wersji.

Pomysły typu - lokalne edytowanie gema/dodawania monkey-patchów to porażka - przenieś to potem na serwer produkcyjny, albo zintegruj zmiany, które pojawiły się w oryginalnej wersji biblioteki.
A w Gicie możesz wywołać:

git pull --rebase origin master

i jeśli jest jakiś konflikt, to dokładnie wiesz gdzie. Ponadto możesz odpalić oryginalne testy, etc. Potem tylko “bundle update” i po sprawie.

Podsumowując - możliwość dodania w Bundlerze zależności do repozytorium Gita znakomicie ułatwia utrzymywanie własnych wersji bibliotek.

Jak zaczniesz być profesjonalistą i zarabiać na swojej pracy, to płatne konto na githubie za równowartość niecałej godziny Twojej pracy przestanie być takie przerażające :wink:

Tak

Ale przecież ten sam argument można przystawić do utrzymywania własnego forka. Czyli jeśli chcesz upgrade’ować, musisz zrobić merge głównego repozytorium (upstream) i mieć nadzieję, że w oryginalnej bibliotece nie zmieniły się właśnie te linijki, które nadpisałeś, bo wtedy masz ładny merge conflict. Przy takiej perspektywie utrzymywanie własnego monkeypatcha jednej metody wydaje się co najmniej tak samo dobrym, jeśli nie lepszym od utrzymywania forka pomysłem.

Oczywiście zdecydowanie wolę zrobić forka, ale to wyłącznie dlatego, żeby w bliższej lub dalszej przyszłości wysłać właścicielowi biblioteki pull requesta. To jest już w ogóle super sprawa (jeśli się uda, a w świecie Ruby niespaprany kod z reguły wchodzi), bo wtedy nie musisz utrzymywać tych kilku nowych linijek kiedy już wejdą do upstream. W ten sposób Ty zmniejszasz sobie ilość kodu do utrzymywania (profit!), a reszta społeczności nie musi go samodzielnie implementować (profit! profit for everyone!). Jako idealista uwielbiam scenariusze typu win-win.

Jeszcze co do trzymania własnych nadpisań (słowo “monkeypatch” brzmi mi coraz bardziej wulgarnie), to jest to oficjalna polecana metoda na customizację m.in. Devise. Czy powiedziałeś już Jose że Twoim zdaniem to debilizm? :wink:

Nie piszę, że debilizm, ale porażka :slight_smile: Nie uważam, że to debilizm, ale w kontekście możliwości określenia dependecy na repozytorium Gita, to jest to moim zdaniem zdecydowanie gorsze rozwiązanie. Co nie zmienia faktu, że w kilku projektach sam je wykorzystuję - ale tylko dlatego, że nie korzystają z bundlera.

No i różnica między monkey patchem a zmianami trzymanymi w repo właśnie polega na tym, że jeśli chcesz mieć nowszą wersję to możesz spróbować zmergować ją z twoimi zmianami. Możesz odpalić testy w izolacji (poza twoją aplikacją). Jeśli będą błędy to będziesz o tym wiedział - albo przy merge’u, albo przy odpaleniu testów.

Co więcej - jak masz kilka aplikacji, które wymagają zmian w bibliotece, to też trzymasz to tylko w jednym miejscu, a nie w każdej aplikacji z osobna.

Reasumując - monkey patching bibliotek nie jest debilizmem, ale obiektwynie gorszym rozwiązaniem problemu, niż trzymanie własnej wersji biblioteki w gicie.

Obiektywnie Twoim zdaniem :wink: