środa, 21 grudnia 2011

#next na każdym znaku Stringa

Jakiś czas temu deliberowaliśmy ( :] ) na forum jak najszybciej i najbardziej elegancko rozwiązać wywołanie #next na każdym znaku Stringa. Jeżeli ktoś nie wie jak działa String#next:


Niestety jeżeli wywołamy #next na ciągu znaków nie zadziała tak jakbyśmy chcieli:

środa, 14 grudnia 2011

Mongoid: polimorficzne embeds_one

Nie da się


Załóżmy, że nasza aplikacja ma model MediaObject, który posiada tytuł, głosy itd. ale specyficzne informacje n/t obiektu (treść/link etc.) są w innym modelu (Media::Text, Media::Image etc.). Relacja oczywiście jeden-do-jeden. Jeżeli zrobimy to na zasadzie referenced assosiation, czyli relacje rodem z baz SQL, będziemy mieli zawsze n+1 zapytań. Mongoid co prawda obsługuje eager loading, ale nie dla relacji polimorficznych. Co więc możemy zrobić?

Tworzymy model MediaObject:

Oraz model Media::Resource - po nim będą dziedziczyć wszystkie modele z modułu Media

Teraz możemy dodać np. model Media::Text

Użycie:


Żeby ułatwić sobie życie, możemy wydelegować #content do MediaObject

Opcja allow_nil pozwala trzymać w #content pustą wartość. W tym przypadku to bardzo ważne, bo nie wiemy czy napewno wszystkie modele Media będą miały taką metodę. Gdyby nie miały, bez tej opcji model zawrze rzucał by wyjątek. Teraz użycie wygląda tak:

wtorek, 13 grudnia 2011

Bump to 1.9.3-p0

Dzisiaj (dopiero) zrobiłem update Ruby do wersji 1.9.3-p0. Dużo naczytałem się o poprawie startu appki, wykonywaniu testów itd.

Sprawdźmy jak to wygląda w praktyce :)


Po zainstalowaniu odpaliłem testy powstającej (a więc narazie niedużej) aplikacji Railsowej (Rails 3.1.3)

Ruby 1.9.2

Ruby 1.9.3

Średnie czasy:
Ruby 1.9.2 =~ 16.69
Ruby 1.9.3 =~ 11.12(!)

A więc różnica ponad 5.5s. Całkiem sporo jak na 140 testów.

Update'ować? Opinie są różne, ale wydaje mi się, że jeżeli ma się dobrze otestowaną aplikację można spróbować. Jeśli testy przejdą to po co tracić codziennie te kilka minut (5s * odpalanie_testów_miliard_razy)?

niedziela, 27 listopada 2011

Ruby & Ruby on Rails 101

Ruby & Ruby on Rails 101. Krótka lista od czego zacząć** (będzie uzupełniana)


Ruby
1. TryRuby (Ruby w 15 minut)
2. Eloquent Ruby (moja "mini recenzja")
3. Desing Patterns in Ruby
4. Klasyk, tzw "Książka z Kilofem" - Programming Ruby

Ruby on Rails
1. Rails for Zombies
2. RailsGuides
3. RailsCasts
4. Ruby on Rails Tutorial


Za książki o Rubym trzeba niestety zapłacić (ale pamiętajmy, że to inwestycja!), natomiast źródła o Railsach są w 100% darmowe (no, RailsCasty przynajmniej do niedawna były w 100% darmowe, teraz część treści tam publikowanych jest płatna) i moim zdaniem wystarczające, aby zacząć pisać proste aplikacje. Książek do Railsów jest multum - począwszy od Agile, przez Rails 3 in Action aż po Rails 3 Way (ta ostatnia zdecydowanie dla zaawansowanych), ale moim zdaniem nie są one wymagane (tzn. da radę lepiej lub gorzej nauczyć się bez nich)

** głównie do publikacji na forum Ruby on Rails. Tam takie pytania (a co za tym idzie i odpowiedzi) padają bardzo często. Zamiast pisać to za każdym razem lepiej odesłać do linka ;)

czwartek, 25 sierpnia 2011

One of keys

Edit: Okej, już wiem, która wersja jest najbardziej RubyWay :)

HashKeys@github - taki sobie o bajer z nudów. Użycie jest bajecznie proste - pobieramy hash_keys.rb (może zrobię z tego gema w wolnym czasie) a następnie:




piątek, 22 lipca 2011

Nie róbcie update'u RubyMine do 3.2.2

Update: okazało się, że wystarczy wybrać z menu File -> Invalidate Caches... i w większości przypadków usuwa to błędy.

Wczoraj pojawił się update (podobno bugfix :/) RubyMine do wersji 3.2.2. Zainstalowałem, uruchomiłem i tzw. "dupa". Podpowiadanie składni przestało działać, skok do definicji przestał działać podgląd dokumentacji przestał działać (pewnie więcej rzeczy nie działało, tyle udało mi się zauważyć zanim zrobiłem downgrade). Wszystko się wysypało.


Wywaliłem w cholerę, zainstalowałem 3.2.1 (musiałem niestety wywalić całą konfigurację) i działa.


Radzę poczekać z aktualizacją na kolejną wersję (3.2.3?)

poniedziałek, 11 lipca 2011

niedziela, 19 czerwca 2011

Kod, który zawsze działa!

Remember, a great way to avoid broken code is to have less of it. The code that you never write will work forever.
- Russ Olsen, "Eloquent Ruby" (Addison-Wesley Professional, 2011)

piątek, 17 czerwca 2011

Pisz "elokwentnie" w Rubym

Nie trudno nauczyć się nowego języka programowania. W końcu wszędzie mamy te same if-y, pętle, klasy, funkcje. Trochę czasu zajmuje oczywiście poznanie biblioteki standardowej i pewnych konstrukcji typowych dla danego języka.

Sztuką jednak poznać jest styl danego języka. Wiedzieć kiedy użyć danej konstrukcji, znać idiomy, zasady którymi rządzi się język.
 W innym wypadku jest duża szansa, że nie piszesz w Rubym, ale jakimś innym języku, który znałeś wcześniej. Wtedy trzeba sobie zadać pytanie: to po co udawać, że się pisze w Rubym?

Tutaj z pomocą przychodzi nam świetna książka - "Eloquent Ruby" autorstwa Russa Olsena 
It’s easy to write correct Ruby code, but to gain the fluency needed to write great Ruby code, you must go beyond syntax and absorb the “Ruby way” of thinking and problem solving. In Eloquent Ruby, Russ Olsen helps you write Ruby like true Rubyists do–so you can leverage its immense, surprising power.
Olsen draws on years of experience internalizing the Ruby culture and teaching Ruby to other programmers. He guides you to the “Ah Ha!” moments when it suddenly becomes clear why Ruby works the way it does, and how you can take advantage of this language’s elegance and expressiveness.
Eloquent Ruby starts small, answering tactical questions focused on a single statement, method, test, or bug. You’ll learn how to write code that actually looks like Ruby (not Java or C#); why Ruby has so many control structures; how to use strings, expressions, and symbols; and what dynamic typing is really good for.
Next, the book addresses bigger questions related to building methods and classes. You’ll discover why Ruby classes contain so many tiny methods, when to use operator overloading, and when to avoid it. Olsen explains how to write Ruby code that writes its own code–and why you’ll want to. He concludes with powerful project-level features and techniques ranging from gems to Domain Specific Languages.
A part of the renowned Addison-Wesley Professional Ruby Series, Eloquent Ruby will help you “put on your Ruby-colored glasses” and get results that make you a true believer.
Nie jest to książka, która wyjaśni nam podstawy programowania (co to jest zmienna, pętla czy obiekty). Autor zakłada, że znamy już trochę Ruby'ego na tyle żeby pisać poprawne (działające) programy. Jednak nie na tyle dobrze żeby pisać je poprawnie (zgodne z duchem Ruby'ego).

W sumie dopiero w trakcie lektury Ruby mnie zafascynował. Do tej pory był tylko "pośrednikiem" pomiędzy mną a Railsami, a sam w sobie mnie nie porywał.


czwartek, 16 czerwca 2011

Lepsze wsparcie dla YARD w nowym RubyMine (3.2)

Dobrze jest pisać komentarze i dokumentować kod - to wie każdy. Nowoczesne IDE potrafią dzięki dobrze zbudowanej dokumentacji lepiej podpowiadać kod (potrzebne parametry i ich typ, typ zwróconej wartości itd.)

Nowa wersja RubyMine (3.2) wprowadza lepszy support dla YARD. Sprawa jest generalnie prosta. Piszemy odpowiednio komentarze nad kodem używając składni YARD:


Dzięki czemu uzyskujemy lepsze podpowiedzi:


poniedziałek, 13 czerwca 2011

Template inheritance w Rails 3.1 - DRY niczym Briana Banks

Wielkimi krokami zbliża się wersja 3.1 frameworka Ruby on Rails, a wraz z nią wiele ciekawych ficzerów jak na przykład reversible migrations czy mountable engines. Jako genialny wynalazek zostało również wprowadzone template inheritance:
As the name implies, inherited templates make template lookup follow the controller inheritance heirarchy if it can’t find a template for the current controller.
Najłatwiej będzie to opisać fragmentami kodu.


Fragment kodu, który odpowiada za menu możemy przenieść do katalogu app/views/application, ponieważ każdy kontroler dziedziczy po ApplicationController.


Do tej pory wszystko wygląda wspaniale. Co jednak, jeżeli chcielibyśmy dodać jedną pozycję w menu np. dla NewsController? Nic prostrzego. Tworzymy app/views/news/_menu.html.erb w którym dodajemy link. Wspaniale! Co jednak, jeżeli mamy bardzo rozbudowane menu a dla jednego kontrolera chcemy dodać 1 (JEDNĄ!) pozycję? Tak! Musimy skopiować cały plik i dodać tylko ten 1 link. Don't Repeat Yourself pełną gębą.

System szablonów (nie mówię o języku szablonów, ale bardziej o tym jak działa mechanizm ich ładowania, przekazywania do nich zmiennych itd.) w Rails nigdy mnie nie powalał. Dużo bardziej podoba mi się ten znany z Django. Mamy w nim tzw. bloki. Przenosząc ten mechanizm na nasz przykład mielibyśmy blok menu w głównym szablonie (application.html.erb) i bloki rozszerzające go w poszczególnych szablonach. Wyglądałoby to mniej więcej tak:


Prawda że wygodniej, schludniej i bardziej DRY?




Briana Banks (ur. 21 maja 1978 w Monachium) - niemiecka aktorka występująca w filmach pornograficznych. [wikipedia.org] [która zdecydowanie nie jest dry (sucha) - autor]

środa, 8 czerwca 2011

Java-Szkoły i kurs 6.001 (MIT)

Jakiś czas temu przeczytałem wpis Joel'a Spolsky'ego n/t "Java-Szkół". Tych, którzy chcą zapoznać się z wpisem odsyłam do oryginału [polskie tłumaczenie]. Blogosfera zawrzała - komentarze pod każdym z wpisów, wpisy typu "What if I went to a Java school, Joel?". Ale nie o tym wpis, nie będę (przynajmniej teraz) polemizował ze zdaniem Spolsky'ego.

Joel wychwala za to kurs 6.001 Structure and Interpretation of Computer Programs
This course introduces students to the principles of computation. Upon completion of 6.001, students should be able to explain and apply the basic methods from programming languages to analyze computational systems, and to generate computational solutions to abstract problems. Substantial weekly programming assignments are an integral part of the course. This course is worth 4 Engineering Design Points.
Kurs chociaż bardzo stary (pierwsze wydanie podręcznika - 1985) jest bardzo ciekawy i warty obejrzenia. Tak, obejrzenia. Dostępne są nagrania wideo całego kursu prowadzonego przez twórców języka Scheme Guy'a L. Steele'aGerald'a Jay Sussman'a. Co prawda sam Scheme nie jest dzisiaj szeroko używany, ale coraz popularniejszy staje się inny dialekt Lisp-a - Clojure (sam dzięki 6.001 zainteresowałem się Lispem i Clojure właśnie).








Download:

niedziela, 27 marca 2011

Kick-ass language

Haskell was made by some really smart guys (with PhDs) (...) when a committee of researchers got together to design a kick-ass language.
- Miran Lipovaca "Learn You a Haskell for Great Good!: A Beginner's Guide" (No Starch Press, 2011)

środa, 23 marca 2011

Rails3: respond_with i pusty json/xml/yaml przy update

W Rails3 możemy zamiast (bardzo "nie-DRY") bloku respond_to:


możemy ustawić raz w jaki sposób chcemy odpowiadać na request:

dużo ładniej prawda? :)

Jest jednak jeden problem - przy akcji update (czy każdej innej do której dostajemy się poprzez PUT) Rails zwraca status OK (200) zamiast zmienionego obiektu. Może czasem to dobrze, możliwe, że to nawet bardziej zgodne ze specyfikacją REST, tego nie wiem. Wiem tyle, że potrzebowałem aby update zwracało obiekt. Można zrobić to na 3 sposoby - dobry, okropny, jeszcze gorszy :) Zacznijmy od końca. Możemy w każdej akcji używać:


Skazujemy się jednak na jeden format zwracanych danych. Możemy wrócić znowu do bloku respond_to (to jest opcja nr.2 - okropna), lub nadpisać responder.

Tworzymy plik application_responder.rb w katalogu lib/


Następnie zmieniamy ApplicationController (app/controllers/application_controller.rb):


Dzięki temu możemy w akcji update używać respond_with:

niedziela, 20 marca 2011

Za granicą nie wiedzą co to ułamki zwykłe?

Książka Programming in Scala, rozdział Functional Objects, paragraf A specification of class Rational. Czytamy:


A rational number is a number that can be expressed as a ratio n/d , where `n` and `d` are integers, except that `d` cannot be zero. `n` is called the numerator and `d` the denominator. Examples of rational numbers are 1/2 , 2/3 , 112/239 , and 2/1 . Compared to floating-point numbers, rational numbers have the advantage that fractions are represented exactly, without rounding or approximation. 

The class we’ll design in this chapter must model the behavior of rational numbers, including allowing them to be added, subtracted, multiplied, and divided. To add two rationals, you must first obtain a common denominator, then add the two numerators. For example, to add 1/2 + 2/3 , you multiply both parts of the left operand by 3 and both parts of the right operand by 2, which gives you 3/6 + 4/6 . Adding the two numerators yields the result, 7/6 . To multiply two rational numbers, you can simply multiply their numerators and multiply their denominators. Thus, 1/2 ∗ 2/5 gives 2/10 , which can be represented more compactly in its "normalized" form as 1/5 . You divide by swapping the numerator and denominator of the right operand and then multiplying. For instance 1/2 / 3/5 is the same as 1/2 ∗ 5/3 , or 5/6 .

Właśnie, dzięki uprzejmości Panów Ordersky, Spoon, Venners dowiedzieliśmy się czym są ułamki zwykłe, jak je dodawać, mnożyć, dzielić i (uwaga!) skracać. Naprawdę żałuję, że zabrakło miejsca żeby nauczyć nas jak je odejmować.

Zawsze wydawało mi się, że programiści to w miarę inteligentne osoby. Przy okazji raczej uzdolnione matematycznie i w ogóle. Czyżby w Szwajcarii (skąd pochodzi Martin Odersky) ułamki zwykłe były wiedzą tajemną znaną garstce wybrańców (czytaj studentów  École Polytechnique Fédérale de Lausanne, na której M. Ordersky wykłada)?


Mówiąc szczerze bardzo rozbawił mnie ten fragment :)


"Hasło nie zawiera wymaganych znaków"

No cholera jasna! Dajcie mi spokój!


Jak chcę mieć banalne hasło, które złamie pierwszy lepszy piątoklasista to moja sprawa. Chcę mieć 3 znaki? OKEJ. Chcę mieć same cyfry? OKEJ. Chcę mieć hasło w typu #$$%$%&^$#$#%#@@$$%%? OKEJ.

To moja sprawa jakie mam hasło!!!

wtorek, 8 marca 2011

django-piston: Przesyłanie dodatkowych parametrów POST do metody BaseHandler.create()

django-piston daje nam 4 podstawowe metody REST: read(), create(), update(), delete(). Są one bardzo proste i najczęściej musimy je nadpisać, aby uzyskać chciany przez nas efekt.

Metoda create() korzysta domyślnie tylko z parametrów przesłanych w POST (request.POST). Chcąc przesłać do niej dodatkowy parametr lub zmienić istniejący musimy nadpisać całą metodę (i tak kilka razy dla każdego Handlera używajacego create()). Chyba że nadpiszemy tą metodę raz (najlepiej w osobnym pliku, chociażby: libs.my_piston.handler.), aby przyjmowała dodatkowy słownik jako parametr funkcji i (jeżeli zostanie podany) dodała go do słownika pobranego z request.POST.


Teraz w naszym handlerze:

wtorek, 22 lutego 2011

Kolorowanie składni w PyCharm i RubyMine

PyCharm (jak i inne produkty JetBrains) nie posiada defaultowo powalającej liczby schematów kolorowania składni. Mało jest też ich dostępnych w internecie (dobrych, obsługujących jednocześnie język programowania, języki szablonów, pliki yaml itd.). Znalazłem jednak na GitHubie konwerter schematów dla TextMate. Nie działa on idealnie i obsługuje (poza takimi rzeczami jak html, css, js czy yaml) tylko Pythona (i szczątkowo Ruby, chociaż istnieje fork poprawiający obsługę języków z RubyMine - haml, erb i właśnie Ruby). Zawsze jest to jednak coś (no i jakiś punkt wyjścia dla kogoś kto chciałby nad czymś podobnym pracować).

Aby użyć colorSchemeTool (bo tak nazywa się narzędzie) musimy pobrać go z GitHub:
git clone git://github.com/yole/colorSchemeTool.git

A następnie przekonwertować (pobrany wcześniej na dysk) schemat dla TextMate*:
python colorSchemeTool.py nazwa_schematu.tmTheme nazwa_schematu.xml

Uzyskujemy dzięki temu (na podstawie Birds of Paradise - http://joebergantine.com/werkstatt/birds-of-paradise-for-textmate):

* skrypt wymaga Pythona w wersji min. 2.7

Linux + Compiz + Intellij IDEA (/RubyMine/PyCharm/PhpStorm...)

Korzystając z produktów JetBrains (tzn. Intellij IDEA, RubyMine, PyCharm itd) pod Linuxem z włączonym Compizem pojawiać się mogą problemy z interfejsem. Przechodząc pomiędzy opcjami w menu możemy zauważyć błąd:


Można oczywiście problem obejść wyłączając Compiz na czas używania programu, ale ażeby wilk był syty i owca cała dodajemy do pliku *.vmoptions (który znajduje się w katalogu /bin aplikacji) linijkę:
-Dsun.java2d.pmoffscreen=false