Ruby: The Bad Parts [zamknięte]

20

Niedawno przeczytałem książkę Crockforda „JavaScript: dobre części”, a jedną z podstawowych przesłanek było to, że języki programowania mogą mieć złe zestawy funkcji, których programiści powinni unikać.

Jestem rubinistą i choć uwielbiam język, zawsze warto mieć perspektywę. Więc co uważasz za najgorszą funkcję (np. Metody, ćwiczenia, praktyki) w Rubim? Nie zamierzam tutaj spierać się o zalety samego języka lub jego szybkości i tak dalej. Wolałbym raczej dyskusję o tym, jakie funkcje uważasz za niebezpieczne / kłopotliwe / bolesne w użyciu, w oparciu o wcześniejsze doświadczenia.

Jack Kinsella
źródło
1
Nigdy nie byłem fanem używania słowa „koniec”, a wtedy mieszanie tego z „{” i „}” staje się jeszcze bardziej denerwujące. To sprawia, że ​​doceniam składnię w stylu Pythona lub od razu {&}. Chociaż można się z tym kłócić, a ostatecznie ma to wiele wspólnego z osobistymi preferencjami. Słyszałem, jak ktoś powiedział, że Ruby bierze najbrzydsze części Pythona i Perla i łączy je razem. Jednak lubię uczyć się Ruby.
Właściwie podoba mi się to pytanie i nie mogę się doczekać odpowiedzi, ale mimo to głosowałem za jego zamknięciem. Nie sądzę, aby dobrze pasowało do przepełnienia stosu (z powodu potencjalnie zbyt subiektywnej / argumentacyjnej, otwartej itd.).
stakx
Myślę, że warto o tym dyskutować, ponieważ mogłoby to naświetlić niebezpieczne praktyki, których należy unikać. Rozumiem jednak twój punkt widzenia i zredagowałem pytanie, aby było bardziej zawężone.
9
Nie rozumiem, w jaki sposób to pytanie jest wystarczająco wyraźne, np. Jakie rzeczy chciałbyś poprawić w języku Ruby? , O jakich Rubinowych Gotchach powinien ostrzegać nowicjusz? , Jakie są rzeczywiste problemy z Ruby? lub którekolwiek z pozostałych pytań gazillionowych na temat bólu Ruby. Co więcej, nawet jeśli to pytanie ewoluuje w celu odróżnienia się od innych, należałoby do Programmers.SE , a nie StackOverflow.
Jörg W Mittag
2
Muszę sprawdzić oczy - myślałem, że tytuł tego pytania brzmi „Ruby: Brad Brads”.
oosterwal 28.03.11

Odpowiedzi:

8

Powinieneś obejrzeć Python vs Ruby: A Battle to The Death w reżyserii Gary'ego Bernhardta. Robi cytat:

To, co uważam za brzydkie w Rubim, sprawia, że ​​niesamowite oprogramowanie Ruby, takie jak RSpec, jest możliwe i którego Python nigdy nie mógłby mieć (biorąc pod uwagę bieżącą implementację).

Podczas gdy dużo mówi w szczególności o Pythonie, dotyka wielu rzeczy, które są po prostu dziwne w Ruby. Jednym z głównych tematów jest łatanie małp .

Obiekty Ruby (w przeciwieństwie do obiektów w niektórych innych językach obiektowych) mogą być indywidualnie modyfikowane. Zawsze możesz dodawać metody dla poszczególnych obiektów. W Rubim zachowanie lub możliwości obiektu mogą różnić się od tych dostarczonych przez jego klasę.

Chociaż zapewnia to dużą elastyczność i moc niektórych najpopularniejszych i najbardziej skomplikowanych klejnotów Ruby, może ugryźć cię w tyłek, jeśli próbujesz debugować problem, nie zdając sobie sprawy, że jakaś biblioteka gdzieś zmodyfikowała podstawową metodę.

Michelle Tilley
źródło
JavaScript pozwala również traktować obiekty w ten sposób.
0112
8

Niektórzy ludzie myślą o ruby ​​tylko w kategoriach rubinu na szynach i jest to trochę denerwujące, ponieważ język radzi sobie całkiem dobrze.

davidk01
źródło
7

Myślę, że najgorszą funkcją jest open classesglobalna zmiana zachowania wszystkich obecnych i przyszłych instancji zmienionej klasy.

Problematyczną częścią tej funkcji jest to, że tezy (globalne) zachodzą w czasie wykonywania, gdy interpreter języka Ruby natrafi na definicję, co może potrwać długo po utworzeniu instancji kilku obiektów, które nagle zmieniają swoje zachowanie.

W dużej bazie kodu może to prowadzić do bardzo, bardzo trudnych do znalezienia błędów - zwłaszcza, że ​​pogarsza to słaba (w porównaniu np. CLR lub JVM) historia debugowania i użycie innych funkcji (np. eval) W tym kontekście może sprawić, że trudno jest znaleźć lokalizację, w której nastąpiła ta globalna zmiana. tzn. jeśli osiągnąłeś już punkt, w którym podejrzewasz, że „właściwa” klasa powoduje problemy! Z mojego doświadczenia wynika, że ​​zwykle zaczynasz od pogoni za gęsią skórką, ponieważ problemy zaczynają pojawiać się na obiekcie przy użyciu prawdziwego winowajcy.

Najlepszą rzeczą byłoby zatem zaprzestanie korzystania z otwartych klas ( #extenda umieszczenie zmian w ModuleIMHO jest znacznie bezpieczniejsze, łatwiejsze do zrozumienia i lepiej przetestować) lub jeśli nie można tego uniknąć:

  • rozszerzaj klasy tylko o nowe zachowanie (tzn. nie zastępuj istniejącego zachowania)
  • mają określone miejsce w drzewie kodu źródłowego, w którym należy umieścić wszystkie rozszerzenia korzystające z klas otwartych
  • nie używaj #evali znajomych do tworzenia otwartych zajęć
  • umieść wszystkie zastosowania klas otwartych na dużym widocznym wykresie, na którym wszyscy programiści mogą je zobaczyć - i wyjaśnij, że wszelkie zmiany na nich są „decyzjami architektonicznymi” wpływającymi na całą bazę kodu (co robią), a nie miejsce na szybkie hacki przydatne do bieżącego zadania
Alexander Battisti
źródło
5

Największy powód, dla którego nie używam Ruby: Jest wolniejszy niż melasa w styczniu na biegunie północnym podczas epoki lodowcowej. Języki testów porównawczych są niedokładną nauką, ale Ruby wydaje się znacznie wolniejsza niż nawet JavaScript i Python.

dsimcha
źródło
to też było moje doświadczenie.
Chuck Stephanski
2
do jakiej aplikacji napisałeś, dla której rubin jest zbyt wolny? Mam na myśli, że wierzę ci, kiedy mówisz, że jest powolny, ale jak to powstrzymało cię od osiągnięcia celu?
David
1
Myślę, że Ruby jest świetny, gdy chcesz zrobić coś w rodzaju prototypu i chcesz, aby to się stało szybko, coś, co nie jest ogromne i nie będzie powodowało masowego zgniatania liczb. Jeśli spodziewasz się ciągłego żucia wielu cykli procesora, każdy dobry programista wie, że używa czegoś takiego jak C lub C ++.
Jeff Welling
1
@David: Rozważałbym użycie Ruby do prostego kodu przetwarzania sekwencji DNA, ale nie robię tego, ponieważ Python wypełnia podobną niszę, ma podobne funkcje i jest znacznie szybszy. Jeśli chcę zejść na niższy poziom, D jest jeszcze szybszy i wciąż wygodny.
dsimcha
1
@Jeff: Zgadzam się, ale C i C ++ są kłopotliwe w pisaniu. Istotą języków wysokiego poziomu, takich jak Ruby, jest unikanie radzenia sobie z tym bólem w jak największym stopniu. Im wolniej są, tym gorzej osiągają ten cel. Ruby działa wolno nawet w przypadku dynamicznego języka wysokiego poziomu. Właśnie dlatego i NumPy / SciPy używam Pythona, gdy potrzebuję dynamicznego języka wysokiego poziomu.
dsimcha
4

Jeśli można to rozszerzyć na Ruby on Rails, to:

  1. Fakt, że logika bazy danych nadaje każdej tabeli auto_incrementpodstawowy klucz, w tym tabele, które ich nie potrzebują i nie powinny ich mieć.

  2. Fakt, że klucze złożone nie są w ogóle obsługiwane.

Dla zwykłego Ruby mój problem byłby taki sam jak dla każdego języka, który zamienia bezpieczeństwo na ekspresję; łatwo jest zrobić wiele za pomocą małego kodu, ale równie łatwo jest zrobić wielki bałagan przy dowolnej ilości kodu.

aroth
źródło
Proszę zobaczyć moje zmiany, gdy zawęziłem zakres pytania. Rozpocznę kolejną równoległą dla Railsów, jeśli to pytanie z edycjami zostanie zatwierdzone.
1
Przykro nam, ale się mylisz, nie każda tabela w aplikacji Rails musi mieć auto_incrementidentyfikator, a zwłaszcza dołączanie do tabel w relacjach has_and_belongs_to_many sugeruje się, aby jawnie NIE miały kolumny identyfikatora.
Brett Bender
@Brett - Czy są to stosunkowo nowe dodatki? Kiedy grałem z nim na początku 2008 roku, zdecydowanie nie miał tych funkcji. W każdym razie to świetnie, że są już dostępne.
1
@aroth: Nie jestem pewien, czy wszyscy inni uznaliby, że „stosunkowo nowy” oznacza „w ciągu ostatnich trzech lat” :-)
Istnieje alternatywa dla ActiveRecord Railsów o nazwie DataMapper , która nie jest tak pozytywna jak ActiveRecord.
Endy Tjahjono
3

Ruby obejmuje metaprogramowanie (refleksja, introspekcja), programowanie z wieloma paradygmatami i dynamikę na niespotykanym poziomie. Łatwo jest strzelać w stopę dzięki sile i elastyczności.

Kłopotliwy? Ruby może być wyjątkowo czytelny lub niezniszczalny. Widziałem kod, który wygląda, jakby należał do skryptu Bash.

Złe praktyki? Niektórzy rubiści cenią spryt nad mądrością. Piszą i dzielą się sztuczkami, które pokazują ich spryt, ale tworzy to nieczytelny i delikatny kod.

Nawiasem mówiąc: Javascript był z założenia katastrofą, a książka „The Good Parts” próbuje wydobyć ukryte piękno. Perl, język, który spopularyzował „Jest więcej niż jeden sposób na to” (czyli elastyczność), ma podobną książkę w „Perl, Best Practices”. Historia Perla to historia eksperymentów i ciężko zdobytych doświadczeń. „Najlepsze praktyki” reprezentują jej wiedzę. Perl 6 będzie, jak sądzę, uczciwym powiedzeniem, restartem języka opartym na tej wiedzy i nie tylko. Ruby może cierpieć z powodu podobnych problemów.

@James i pętle ... Kiedy robisz pętlę for w ruby, wówczas wywołuje „.each”. Dlatego „for” to cukier składniowy dla osób bardziej komfortowych z pętlami w stylu C. Ale jako Rubyista będziesz przez cały czas używać iteratorów takich jak .map, .inject, .each_with_object. Nigdy nie będziesz musiał pisać pętli for z czymś takim jak „i = 0; i> 6; i ++” w ruby, więc w końcu porzucisz nawyk. @ andrew ... elokwentny rubin nie popiera pętli.

autodidakto
źródło
-1

Chodzi bardziej o programistów niż język, ale dlaczego programiści Ruby tak bardzo nienawidzą pętli?

Zdaję sobie sprawę, że Ruby:

someCollection.each do |item|
   ...
end

ale nigdy nie widziałem tego używanego w sytuacjach, w których pętla for nie zrobiłaby dokładnie tego samego.

Pytałem kilka razy i nigdy nie uzyskałem dobrej odpowiedzi na to pytanie.

Jeśli jest to tylko styl, cieszę się, że to akceptuję, ale widziałem, jak programiści Ruby naprawdę się tym zajęli i jestem naprawdę ciekawy.

James
źródło
1
Kiedyś nawet dostałem odpowiedź „To mniej naciśnięć klawiszy”, co jest wyraźnie fałszywe ... :-)
James
2
Dwie teorie: 1) Używanie forpętli jest czymś, co robi n00bs. Ludzie, którzy programują C w Ruby. 2) Bloki są często używane w Ruby, więc używanie czegoś, co nie jest podobne do bloku, to tylko dodatkowy wysiłek umysłowy.
Andrew Grimm,
3
Kiedy zacząłem uczyć się Rubiego, bloki są czymś, co naprawdę lubię i tęsknię, gdy próbuję używać Pythona. Czy pętla for zrobiłaby to samo? Oczywiście dla mnie ten styl bardziej odpowiada moim preferencjom niż pętla for.
Jetti
2
@ andrew Szczerze mówiąc, twoja pierwsza odpowiedź jest dokładnie tym rodzajem śmieci, które otrzymałem, kiedy wcześniej o to zapytałem. Bez prawdziwego powodu, z subtelną zniewagą na górze. @Wayne, @Jetti i @andrews 2. odpowiedź: dzięki. Wystarczająco więc.
James
1
Jeśli masz na myśli „ulepszone” dla pętli (aka. Dla <wartość> w <wyrażeniu> do ...), nie ma różnicy poza # każdym użyciem i wyglądem zbliżonym do jego powszechnie używanych kuzynów #inject, #collect, # odrzuć itp. Jeśli mówisz o pętlach indeksowanych w stylu „C” (aka. dla int i = 0; i <cokolwiek; ++ i) różnica polega na tym, że a) błędy „wyłączone o jeden” są niemożliwe ib) że wyjaśnia intencję pętli - każde z nich oznacza „każdy element wywołuje efekt uboczny”. Pętla for wymaga od Ciebie przeczytania całej pętli, aby uzyskać „sens” jej przeznaczenia.
Alexander Battisti
-1

Generalnie unikałbym rzeczy, które zostały dodane tylko po to, by były kompatybilne wstecz z innymi językami. Na przykład Perlizmy i for x in y.

Andrew Grimm
źródło
Właśnie zamieściłem odpowiedź na temat programistów Ruby i pętli, a jeśli możesz wyjaśnić, byłbym wdzięczny :-)
James