Рубі: погані частини [закрито]


20

Нещодавно я прочитав книгу Крокфорда "Javascript: хороші частини", і однією з основних припущень було те, що мови програмування можуть мати погані набори функцій, яких програмісти повинні уникати.

Я рубіст, і хоча люблю мову, яку завжди важливо отримати перспективу. Отже, що ви вважаєте найгіршою особливістю (наприклад, методи, класи, практики) у Ruby? Мій намір тут - не починати аргументи щодо достоїнств самої мови чи її швидкості тощо. Я скоріше віддаю перевагу дискусії про те, які функції ви вважаєте небезпечними / клопітними / болісними у використанні, виходячи з минулого досвіду.


1
Я ніколи не любив використовувати слово "кінець", і тоді суміш цього слова з "{" і "}" стає ще більше дратує. Це змушує мене цінувати або синтаксис стилю Python, або прямо вгору {&}. Хоча з цим можна сперечатися і вперед, і в кінцевому рахунку це має багато спільного з особистими уподобаннями. Я чув, як хтось каже, що Рубі бере найгірші частини Пітона і Перла і з'єднує їх. Я насолоджуюсь навчанням Ruby.

Мені справді дуже подобається це питання і я з нетерпінням чекаю відповідей, але все-таки проголосував за його закриття. Я не думаю, що це добре підходить для переповнення стека (через те, що потенційно може бути занадто суб'єктивним / аргументативним, відкритим тощо).
stakx

Я думаю, що варто обговорити, оскільки це може висвітлити небезпечні практики, яких слід уникати. Я бачу вашу думку, хоча і відредагував це питання більш вузьким.

9
Я не бачу, наскільки це питання досить відрізняється від, наприклад, які речі ви хотіли б покращити мовою Ruby? , Про що слід попередити новачка в Ruby Gotchas? , Які проблеми в реальному світі з Рубі? або будь-яке інше питання, що стосується болю в Рубі. Плюс, навіть якщо це питання розробляється для того, щоб відрізняти себе від інших, воно належало б до Programmers.SE , а не StackOverflow.
Йорг W Міттаг

2
Мені потрібно перевірити очі - я подумав, що назва цього питання була "Рубі: Бред Піттс".
oosterwal

Відповіді:


8

Ви повинні дивитися на Python vs Ruby: Битва до смерті від Gary Bernhardt. Він робить цитату:

Самі речі, які я вважаю потворними в Ruby, - це те, що робить дивовижним програмне забезпечення Ruby, таким як RSpec, і що Python ніколи не міг (з огляду на поточну реалізацію).

У той час як він багато говорить про Python, зокрема, він торкається багатьох речей, які у Рубі просто дивні. Одним з найбільших загальних предметів є лачання мавп .

Об'єкти Ruby (на відміну від об'єктів у деяких інших об'єктно-орієнтованих мовах) можна змінювати індивідуально. Ви завжди можете додавати методи на основі об'єкта. У Ruby поведінка або можливості об'єкта можуть відхилятися від тих, що надаються його класом.

Хоча це забезпечує велику гнучкість та повноваження деяких найпопулярніших і найскладніших дорогоцінних каменів Рубі, вона може вкусити вас в зад, якщо ви намагаєтеся налагодити проблему, не розуміючи, що десь бібліотека десь змінила основний метод.


Javascript дозволяє вам також обробляти об'єкти.
0112.

8

Деякі люди думають про рубін лише з точки зору рубіну на рейках, і це наче дратує, оскільки мова стоїть сама по собі.


7

Я думаю, що найгірша особливість полягає в тому, open classesщо дозволяють глобально змінити поведінку всіх поточних та майбутніх примірників зміненого класу.

Проблемною частиною цієї особливості є те, що тези (глобальні) зміни трапляються під час виконання, коли інтерпретатор Ruby наштовхується на визначення, яке може бути задовго після того, як ви вже створили кілька об'єктів, які тепер раптом змінюють їх поведінку.

У великій базі коду це може призвести до дуже, дуже важко знайти помилок - тим більше, що це ускладнюється слабкою Рубі (у порівнянні, наприклад, з CLR або JVM) історією налагодження та використанням інших функцій (наприклад eval) у цьому контексті може зробити досить важко знайти місце, де відбулася ця глобальна зміна. тобто якщо ви вже дійшли до того, що ви підозрюєте, що "правильний" клас спричинив проблеми! З мого досвіду, ви зазвичай починаєте з погоні за дикими гусками, оскільки проблеми починають виникати на об'єкті, використовуючи справжнього винуватця.

Тож найкраще було б або припинити використання відкритих класів ( #extendа введення змін у ModuleIMHO набагато безпечніше, простіше зрозуміти і краще перевірити), або якщо цього не вдасться уникнути:

  • розширювати заняття лише новою поведінкою (тобто не змінюючи існуючу поведінку)
  • мають визначене місце у дереві вихідного коду, де мають бути розміщені всі розширення, що використовують відкриті класи
  • не використовувати #eval та друзів для створення відкритих занять
  • помістіть усі звички відкритих класів на велику видиму діаграму, де всі розробники можуть їх побачити - і поясніть, що будь-які зміни на них - це "архітектурні рішення", що впливають на всю базу коду (що вони роблять), а не місце для швидких хакерів корисними для вашого поточного завдання

5

Найбільша причина, що я не використовую Рубі: це повільніше, ніж патока в січні на Північному полюсі під час льодовикового періоду. Мови бенчмаркінгу - це неточна наука, але Ruby виглядає різко повільніше, ніж навіть JavaScript та Python.


це був і мій досвід.
Чак Стефанський

2
яка програма, яку ви розробили, для якої рубін був надто повільним? Я маю на увазі, я вірю тобі, коли ти кажеш, що це повільно, але як це заважало тобі досягти своєї мети?
Девід

1
Я думаю, що Рубі - це чудово, коли ти хочеш зробити щось на зразок прототипу, і хочеш, щоб це було зроблено швидко, те, що не є величезним, і не буде робити масового скорочення чисел. Якщо ви очікуєте, що постійно пережовуєте багато циклів процесора, будь-який хороший програміст знає використовувати щось на зразок C або C ++.
Джефф Веллінг

1
@David: Я б розглядав можливість використання Ruby для простого коду обробки послідовностей ДНК, але я цього не роблю, тому що Python заповнює подібну нішу, має схожі риси і набагато швидше. Якщо я готовий піти на нижчий рівень, D ще швидше і все-таки зручніше.
dimimcha

1
@Jeff: Погоджено, але C і C ++ - це біль писати. Суть мов високого рівня, як Рубі, полягає в тому, щоб максимально уникати боротьби з цим болем. Чим вони повільніше, тим менш добре вони виконують цю мету. Рубі повільно навіть для динамічної мови високого рівня. Це і NumPy / SciPy, тому я використовую Python замість цього, коли мені потрібна динамічна мова високого рівня.
дзимча

4

Якщо це можна поширити на Ruby on Rails, тоді:

  1. Той факт, що логіка бази даних надає кожній таблиці auto_incrementпервинний ключ, включаючи таблиці, які їм не потрібні та не повинні їх мати.

  2. Те, що складні ключі взагалі не підтримуються.

Для простої Рубі моє захоплення було б таким же, як і для будь-якої мови, яка торгує безпекою для виразності; легко зробити багато всього лише з невеликим кодом, але так само легко зробити величезний безлад з будь-якою кількістю коду.


Будь ласка, дивіться мої редагування, коли я звужував сферу питання. Я розпочну ще одну паралельну для Rails, якщо це питання з правками буде схвалено.

1
Вибачте, але ви помиляєтесь, що не в кожній таблиці додатка Rails потрібно мати auto_incrementідентифікатор, зокрема, приєднати таблиці до відносин has_and_belongs_to_many пропонується явно НЕ мати стовпця ідентифікатора.
Бретт Бендер

@Brett - Це відносно нові доповнення? Коли я грав з ним ще на початку 2008 року, у нього точно не було цих особливостей. У будь-якому випадку, чудово, що вони доступні зараз.

1
@aroth: Я не впевнений, що всі інші будуть вважати "відносно новим" значення "протягом останніх трьох років" :-)

Існує альтернатива ActiveRecord Rails під назвою DataMapper , який не настільки впевнений, як ActiveRecord.
Endy Tjahjono

3

Рубі охоплює метапрограмування (рефлексія, самоаналіз), програмування багато парадигми та динамізм на рідкому рівні. Стріляти в ногу легко з силою та гнучкістю.

Тривожно? Ruby має здатність бути надзвичайно читабельним або незламним. Я бачив код, схожий на те, що він належить до сценарію Bash.

Погані практики? Деякі рубіністи цінують кмітливість над мудрістю. Вони пишуть і діляться хитрощами, які демонструють свою кмітливість, але це створює нечитабельний і крихкий код.

Як осторонь: Javascript був катастрофою з боку дизайну, і книга "Гарні частини" намагається видобути приховану красу. Perl, мова, яка популяризувала "Існує більше, ніж один спосіб зробити це" (тобто гнучкість), має подібну книгу в "Perl, Best Practices". Історія Perl - це досвід експериментів і досвід, який перемагає важко, "Best Practices" представляє свої знання. Perl 6 буде, я думаю, це справедливо сказати, перезавантаження мови, заснованої на цих знаннях та інше. Рубі може страждати від подібних проблем.

@James і для циклів ... Коли ви робите цикл у рубіні, він викликає ".each". Тому "for" - це синтаксичний цукор для людей, які зручніші для циклів стилю C. Але як рубіст, ви постійно будете використовувати такі ітератори, як .map, .inject, .each_with_object. Вам ніколи не доведеться писати цикл for з на зразок "i = 0; i> 6; i ++" в рубіні, і, таким чином, ви втратите звичку. @andrew ... красномовний рубін не схвалює циклів.


-1

Це більше стосується програмістів, ніж мови, але чому програмісти Ruby так сильно ненавидять циклі?

Я розумію, що у Рубі:

someCollection.each do |item|
   ...
end

але я ніколи не бачив, що використовується в ситуаціях, коли цикл for не робив би точно те саме.

Я кілька разів запитував і жодного разу не отримав хорошої відповіді на це.

Якщо це просто річ у стилі, я із задоволенням приймаю це, але я бачив, як програмісти Ruby дійсно попрацювали над цим, і мені дуже цікаво.


1
Одного разу я навіть отримав відповідь "Це менше натискання клавіш", що явно неправдиво ... :-)
Джеймс

2
Дві теорії: 1) Використання forциклів - це те, що n00bs робить. Люди, які програмують С на Рубі. 2) Блоки багато використовуються в Рубі, тому використання чогось не блокового - це лише додаткові розумові зусилля.
Ендрю Грімм

3
Поки я тільки почав вивчати Ruby, блоки - це те, що мені дуже подобається і сумую, коли я намагаюся використовувати Python. Чи зробить цикл for for те саме? Звичайно, для мене такий стиль просто відповідає моїм уподобанням, ніж для циклу.
Jetti

2
@andrew Чесно кажучи, ваша перша відповідь - це саме той сміття, яке я повернув, коли я просив його раніше. Немає справжньої причини з тонкою образою зверху. @Wayne, @Jetti та @andrews 2-а відповідь: спасибі. Ярмарок досить.
Джеймс

1
Якщо ви маєте на увазі "покращений" цикл (ака. Для <значення> в <виразі> зробити ...), немає різниці, крім того, що #each використовується і виглядає ближче до його звичайно використовуваних двоюрідних братів #inject, #collect, # відхилити і т. д. Якщо ви говорите про циклі, що індексуються у стилі "C" (ака. для int i = 0; i <що завгодно; ++ i) різниця полягає в тому, що а) помилки "виключені однією" неможливі і b) що це робить чіткий намір вашого циклу - #each означає "для кожного елемента створювати побічний ефект". Цикл for вимагає, щоб ви прочитали весь цикл лише для того, щоб отримати «суть» його призначення.
Олександр Баттісті

-1

Я взагалі уникаю речей, які були додані просто для того, щоб вони були сумісні з іншими мовами. Наприклад, Перлізми і for x in y.


Я щойно опублікував відповідь про програмістів Ruby і про петлі, і якщо ви можете пояснити, я буду вдячний :-)
Джеймс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.