Refinements

Ruby 2.0 ma zostać oficjalnie wkrótce wydany. Jedną z nowości są Refinements czyli propozycja ruby-core rozwiązania problemów
z monkey patchingiem. Jeśli ktoś nie czytał co oznaczają refinements w obecnej formie w praktyce polecam post Headiusa.

Kilka fragmentów:

With refinements, if you have two different locations in your program where the same method is called on the same object with the same arguments and the object has the same ancestor hierarchy, you might get different results.

At present, nobody knows of an easy way to implement the “module_eval” aspect of refinements. The current implementation in MRI does it in a brute-force way, flushing the global method cache on every execution and generating a new, refined, anonymous module for every call. Obviously this is not a feasible direction to go; block dispatch will happen very frequently at runtime, and we can’t allow refined blocks to destroy performance for code elsewhere in the system.

Polecam też video o Toward a Design for Ruby, w którym to Brian opisuje w jaki sposób nowe ficzery w MRI są dyskutowane i dodawane do języka i swoją propozycję zmian tego procesu.

Odnośnie Refinements jest propozycja aby poprosić ruby-core o nie wydawanie Refinements w Ruby 2.0 z powodu problemów o których pisał Headius. Ficzer potrzebuje więcej czasu, lepszej specyfikacji i lepszego zrozumienia konsekwencji jego pojawienia się w Ruby ( do tej pory niewiele mówiono o konsekwencjach, większość osób po prostu uważa, że refinements magicznie rozwiąże wszystkie ich problemy z monkey patchingiem).

Jest to nowy pomysł dla środowiska Ruby. Możemy przewidzieć pewne problemy, możemy się spodziewać nowych efektów. Na pewno niektóre efekty wydają się straszne.

Pierwszy akapit który przytoczyłeś to według mnie reductio ad absurdum - bo niczym nie różni się to od aktualnej sytuacji z monkey patching. Wystarczy, że pomiędzy dwoma miejscami w kodzie zostanie nadpisana metoda w obiekcie i mamy dokładnie taką samą sytuację jak z Refinements. Jak dla mnie to FUD.

Co do dobrej implementacji module_eval - nikt nie wie jak to zrobić łatwo. I jest to zrozumiałe, bo dodawanie nowej funkcjonalności do języka jest trudne. A trudne rzeczy są trudne. Charles jest mądrym gościem ale to nie znaczy, że wszystko będzie mu przychodziło z łatwością.

Żeby nie mylić pojęć: nie wiem czy refinements są dobre. Ale dopóki nie przetestujemy ich w polu dopóty nie będziemy wiedzieć. Pytanie tylko: czy ruby-core będzie miało jaja wyciąć ten feature w 2.1 jeśli nie będzie on dobrze działał w 2.0?

Różnica jest jednak spora - w jednym przypadku będziesz widział efekt tej zmiany wszędzie, w drugim tylko w jednym konkretnym miejscu.

Skoro ruby-core też tego nie umie zaimplementować dobrze, to już nawet nie chodzi o to, że Charles czy Brian mają ból o to, że ciężko im to będzie zaimplementować - nawet MRI nie wie jak to dobrze zrobić.

Jeżeli to sieknie po wydajności całego kodu, a nie tylko kawałków używających refinements, co sugeruje @headius, to ja bym jednak wolał poczekać na dobrą implementację i później testować.

Skoro już rozmawiamy o przyszłości MRI, to ja tylko dodam, że jak widzę kierunek, w którym idzie Ruby (chociażby http://www.mikeperham.com/2012/11/03/current-thoughts-on-ruby-performance/), to mam ochotę zacząć przerzucać aplikacje na rubiniusa i zacząć bardziej aktywnie go wspierać i ewangelizować. Dalej mam ogromny szacunek do Matza i ludzi, którzy pracuję nad MRI, ale może community pomogłoby im trochę inaczej spojrzeć na to, w którym kierunku należałoby pójść.