Рубин: Плохие части [закрыто]

20

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

Я Rubyist, и хотя я люблю язык, всегда есть ценность в получении перспективы. Итак, что вы считаете худшей особенностью (например, методы, классы, практики) в Ruby? Мое намерение здесь не состоит в том, чтобы начать спор о достоинствах самого языка или его скорости и так далее. Скорее я бы предпочел обсуждение того, какие функции вы считаете опасными / хлопотными / болезненными для использования, основываясь на прошлом опыте.

Джек Кинселла
источник
1
Я никогда не был фанатом необходимости использовать слово «конец», и тогда сочетание этого с «{» и «}» становится еще более раздражающим. Это заставляет меня ценить либо синтаксис в стиле Python, либо прямолинейный {&}. Хотя об этом и можно спорить, и в конечном итоге это во многом связано с личными предпочтениями. Я слышал, как кто-то сказал, что Ruby берет самые уродливые части Python и Perl и собирает их вместе. Мне нравится изучать Ruby.
Мне действительно очень нравится этот вопрос, и я с нетерпением жду ответов, но, тем не менее, проголосовал за его закрытие. Я не думаю, что это хорошо подходит для переполнения стека (из-за того, что он может быть слишком субъективным / аргументным, открытым и т. Д.).
Stakx
Я думаю, что это стоит обсудить, так как это может пролить свет на опасные практики, которых следует избегать. Хотя я понимаю вашу точку зрения и отредактировал вопрос так, чтобы он был более узким.
9
Я не понимаю, насколько этот вопрос достаточно отличим от, например. Что бы вы хотели улучшить в языке Ruby? , Что Рубин Gotchas новичок должен быть предупрежден о? , Каковы реальные проблемы с Ruby? или любой другой вопрос о болевых точках Руби. Кроме того, даже если этот вопрос разработан для того, чтобы отличаться от других, он будет принадлежать Programmers.SE , а не StackOverflow.
Йорг Миттаг
2
Мне нужно проверить свои глаза - я думал, что заголовок этого вопроса был "Руби: Брэд Питтс".
oosterwal

Ответы:

8

Вы должны смотреть Питон против Рубина: Битва за Смерть Гари Бернхардта. Он делает цитату:

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

Хотя он много говорит о Python, в частности, он затрагивает много вещей, которые просто странны в Ruby. Один из главных общих вопросов - исправление обезьян .

Объекты Ruby (в отличие от объектов в некоторых других объектно-ориентированных языках) могут быть изменены индивидуально. Вы всегда можете добавить методы для каждого объекта. В Ruby поведение или возможности объекта могут отличаться от тех, которые предоставляет его класс.

Хотя это обеспечивает большую гибкость и поддерживает некоторые из самых популярных и сложных драгоценных камней в Ruby, оно может вас укусить, если вы пытаетесь отладить проблему, не осознавая, что какая-то библиотека где-то изменила основной метод.

Мишель Тилли
источник
Javascript позволяет обрабатывать объекты таким же образом.
0112
8

Некоторые люди думают о ruby ​​только в терминах ruby ​​на рельсах, и это немного раздражает, потому что язык сам по себе довольно хорош.

davidk01
источник
7

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

Проблемная часть этой функции заключается в том, что эти (глобальные) изменения происходят во время выполнения, когда интерпретатор Ruby сталкивается с определением, что может занять много времени после того, как вы уже создали экземпляр нескольких объектов, которые теперь внезапно меняют свое поведение.

В большой базе кода это может привести к очень, очень трудным для поиска ошибок - особенно потому, что это усугубляется слабой (по сравнению, например, с CLR или JVM) историей отладки, и использование других функций (например eval) в этом контексте может сделать довольно трудно найти место, где произошло это глобальное изменение. то есть, если вы уже достигли точки, когда вы подозреваете, что «правильный» класс вызывает проблемы! По моему опыту, вы обычно начинаете с погони за диким гусем, так как проблемы начинают всплывать на объекте, используя настоящего преступника.

Поэтому лучше всего было бы либо прекратить использовать открытые классы ( #extendи помещать изменения в ModuleIMHO гораздо безопаснее, проще для понимания и лучше тестировать), либо если этого нельзя избежать:

  • расширять классы только новым поведением (т.е. не переопределяя существующее поведение)
  • иметь определенное место в дереве исходного кода, где должны быть размещены все расширения, использующие открытые классы
  • не использовать #evalи друзей для создания открытых классов
  • поместите все виды использования открытых классов на большой видимой диаграмме, где все разработчики могут их видеть, и поясните, что любые изменения в них являются «архитектурными решениями», влияющими на всю кодовую базу (что они делают), а не местом для быстрых полезных хаков для вашей текущей задачи
Александр Баттисти
источник
5

Самая большая причина, по которой я не использую Ruby: он медленнее, чем патока в январе на Северном полюсе во время ледникового периода. Бенчмаркинг языков - это неточная наука, но Ruby выглядит значительно медленнее, чем даже JavaScript и Python.

dsimcha
источник
это был мой опыт тоже.
Чак Стефански
2
какое приложение вы разработали, для которого ruby ​​был слишком медленным? Я имею в виду, я вам верю, когда вы говорите, что это медленно, но как это помешало вам достичь своей цели?
Дэвид
1
Я думаю, что Ruby - это замечательно, когда вы хотите сделать что-то вроде прототипа и хотите, чтобы это было сделано быстро, что-то не очень большое и не будет приводить к массовым переборам чисел. Если вы ожидаете постоянно жевать много циклов ЦП, любой хороший программист знает, что нужно использовать что-то вроде C или C ++.
Джефф Веллинг
1
@ Дэвид: Я хотел бы рассмотреть возможность использования Ruby для простого кода обработки последовательности ДНК, но я этого не делаю, потому что Python заполняет аналогичную нишу, имеет сходные функции и работает намного быстрее. Если я хочу перейти на более низкий уровень, D еще быстрее и все еще удобно.
Дсимча
1
@Jeff: Согласен, но писать на C и C ++ очень сложно. Задача языков высокого уровня, таких как Ruby, состоит в том, чтобы как можно больше избегать этой боли. Чем медленнее они, тем хуже они достигают этой цели. Ruby медленен даже для динамического языка высокого уровня. Именно поэтому и NumPy / SciPy - вот почему я использую Python, когда мне нужен динамический язык высокого уровня.
dsimcha
4

Если это можно распространить на Ruby on Rails, то:

  1. Тот факт, что логика базы данных дает каждой таблице auto_incrementпервичный ключ, включая таблицы, которые не нуждаются в них и не должны иметь их.

  2. Тот факт, что составные ключи не поддерживаются вообще.

Для простого Ruby моя хватка была бы такой же, как и для любого языка, который обменивает безопасность на выразительность; легко сделать много всего с помощью небольшого кода, но так же легко создать огромный беспорядок с любым количеством кода.

aroth
источник
Пожалуйста, смотрите мои изменения, поскольку я сузил сферу вопроса. Я начну другую параллельную версию для Rails, если этот вопрос с правками будет одобрен.
1
Извините, но вы ошибаетесь, не каждая таблица в приложении Rails должна иметь auto_incrementидентификатор, в частности, для объединения таблиц для отношений has_and_belongs_to_many предлагается явно НЕ иметь столбец идентификатора.
Бретт Бендер
@Brett - Это относительно новые дополнения? Когда я играл с ним в начале 2008 года, у него точно не было этих возможностей. В любом случае, здорово, что они доступны сейчас.
1
@aroth: Я не уверен, что все остальные сочли бы «относительно новым» значение «в течение последних трех лет» :-)
Существует альтернатива ActiveRecord от Rails под названием DataMapper , которая не так самоуверенна, как ActiveRecord.
Энди Тяхджоно
3

Ruby охватывает метапрограммирование (рефлексия, самоанализ), многопарадигмальное программирование и динамизм на необычном уровне. Легко выстрелить себе в ногу с силой и гибкостью.

Неудобные? Рубин обладает способностью быть чрезвычайно читабельным или непостижимым. Я видел код, который выглядит так, как будто он принадлежит скрипту Bash.

Плохие практики? Некоторые рубиисты ценят ум за мудрость. Они пишут и делятся трюками, которые демонстрируют их ум, но это создает нечитаемый и хрупкий код.

В дополнение: Javascript был катастрофой по замыслу, и книга «Хорошие детали» пытается раскрыть его скрытую красоту. Perl, язык, который популяризировал «Есть больше, чем один способ сделать это» (то есть гибкость), имеет похожую книгу «Perl, Best Practices». История Perl - это опыт экспериментов и с трудом завоеванный опыт, «Best Practices» представляет его знания. Perl 6 будет, я думаю, справедливо сказать, перезагрузкой языка, основанного на этих знаниях и многом другом. Ruby может страдать от подобных проблем.

@James и for loop ... Когда вы делаете цикл for в ruby, он вызывает ".each". Следовательно, «для» - это синтаксический сахар для людей, которым более комфортно работать с петлями в стиле C. Но как Rubyist вы будете использовать итераторы, такие как .map, .inject, .each_with_object, все время. Вам никогда не придется писать цикл for с чем-то вроде «i = 0; i> 6; i ++» в ruby, и в итоге вы избавитесь от привычки. @andrew ... красноречивый рубин не поддерживает циклы.

autodidakto
источник
-1

Это больше о программистах, чем о языке, но почему программисты на Ruby так ненавидят циклы?

Я понимаю, что Руби имеет:

someCollection.each do |item|
   ...
end

но я никогда не видел, чтобы это использовалось в ситуациях, когда цикл for не делал бы то же самое.

Я спрашивал несколько раз и никогда не получал хорошего ответа на этот вопрос.

Если это просто стиль, я рад принять это, но я видел, как программисты на Ruby очень переживают по этому поводу, и мне действительно любопытно.

Джеймс
источник
1
Однажды я даже получил ответ «Это меньше нажатий клавиш», что явно неверно ... :-)
Джеймс
2
Две теории: 1) Использование forциклов - это то, что делают n00bs. Люди, которые программируют C на Ruby. 2) В Ruby очень часто используются блоки, поэтому использование чего-то не похожего на блок - это просто дополнительные умственные усилия.
Эндрю Гримм
3
Хотя я только начал изучать Ruby, блоки мне очень нравятся, и я скучаю по ним, когда пытаюсь использовать Python. Будет ли цикл for делать то же самое? Конечно, для меня такой стиль больше подходит моим предпочтениям, чем цикл for.
Джетти
2
@andrew Если честно, твой первый ответ - именно тот мусор, который я получил, когда спрашивал раньше. Никакой реальной причины, с тонким оскорблением сверху. @Wayne, @Jetti и @andrews 2-й ответ: спасибо. Достаточно справедливо тогда.
Джеймс
1
Если вы имеете в виду «расширенный» для циклов (он же для <value> в <expression> do ...), нет никакой разницы, кроме того, что #each используется и выглядит ближе к его обычно используемым кузенам #inject, #collect, # отклонить и т. д. Если вы говорите об индексированных циклах в стиле 'C' (иначе для int i = 0; i <что угодно; ++ i) разница в том, что a) ошибки "off by one" невозможны и b) что он проясняет цель вашего цикла - #each означает "для каждого элемента производят побочный эффект". Цикл for требует, чтобы вы прочитали весь цикл только для того, чтобы понять суть его цели.
Александр Баттисти
-1

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

Эндрю Гримм
источник
Я только что опубликовал ответ о Ruby Programmers и циклах, и если вы можете объяснить, я был бы благодарен :-)
Джеймс