ruby


Небольшой пример рефакторинга ruby-кода.

Исходный вариант (взято из статьи Raking /etc/hosts For Sweeter Subdomainage)

hosts = []

# add all the site temporary domains
hosts << Site.find(:all).inject([]) do |collection, site|
  collection << site.harmony_url
end

# add all the account subdomains
hosts << Account.find(:all).inject([]) do |collection, account|
  collection << account.harmony_url
end

Как можно сделать лучше?

Программа-минимум:

# site and account subdomains
hosts = []
hosts << Site.find(:all).collect(&:harmony_url)
hosts << Account.find(:all).collect(&:harmony_url)

Улучшения здесь три:

  1. Заменяем низкоуровневый inject на collect. Нет смысла пользоваться inject и выставлять наружу переменную-счетчик, если можно легко сделать то же самое с более высокого уровня абстракции.

  2. Используем сокращенный способ вызова метода в блоке: (&:harmony_url) вместо {|element| element.harmony_url}. Это улучшение является частью ActiveSupport, так что вне рельс само работать не будет.

  3. Заменяем дословно повторяющие код комментарии на что-то хоть немного более высокоуровневое.

Дополнительная программа:

  1. То же самое чуть компактнее

    # site and account subdomains
    hosts = Site.find(:all).collect(&:harmony_url) + Account.find(:all).collect(&:harmony_url)
    

    Далее в коде нигде не используется факт, что массив хостов содержит два отдельных подмассива со значениями, поэтому можно просто запихать все в плоский массив. Что, кстати, избавит нас не только от инициализации hosts, но и от вызова flatten при использовании значений.

  2. Делаем код понятным без комментариев

    hosts =  Site.find(:all).collect(&:subdomain) +  Account.find(:all).collect(&:subdomain)
    

    … а в классах моделей пишем:

    alias_method :harmony_url, :subdomain
    

Где-то с месяц назад наткнулся на пост Why learning Haskell/Python makes you a worse programmer. Люк Плант (Luke Plant) поднимает крайне актуальную для многих из нас проблему — изучение продвинутых языков не делает вас лучшим программистом на том, что приходится использовать, а, напротив, деморализует и снижает качество работы.

Точка зрения сотрудника

Очень рекомендую прочитать как статью, так и комментарии. Если кратко, приводятся два основных аргумента:

  1. После того, как ты понял и полюбил Python, писать на C# неприятно. Код громоздок и некрасив. Процедурный подход вызывает кучу потенциальных глюков. Кроме того, начав думать на Python, приходится работать “живым компилятором”, переводя эти мысли в C#.

  2. Начав использовать функциональное программирование, пытаешься использовать его везде где только можно. C# не поддерживает многие концепции функционального программирования, в результате чего попытки применять функциональный стиль выглядят уродливо и непонятно. Многие задачи проще решать процедурно.

Люк делает вывод, что нет смысла заниматься самосовершенствованием, если потом не сможешь использовать обретенные навыки.

С изменением среды, на самом деле, все плохо. Шансы рядового программиста или проджект-менеджера изменить политику и стандарты компании, как правило, асимптотически приближаются к нулю. Исключения, когда проектная команда обладает высокой степенью автономности и может использовать какие угодно инструменты, редки как девственность.

В свое время это было одним из факторов, побудивших меня покинуть моего предыдущего работодателя и начать работать на себя.

Добавлю еще, что все относительно. Можно заменить языки в обсуждаемом примере на другие, но проблема останется той же. Есть языки лучше, чем Python и Haskell, есть и множество языков, куда хуже C#. В реальной жизни все еще сложнее, потому что важно не столько качество языка, сколько пригодность его и связанной с ним платформы для решения конкретной задачи.

Точка зрения компании

С другой стороны, компания существует не для того, чтобы развлекать сотрудников. Компания существует для того, чтобы получать прибыль. Соответственно, инструменты выбираются в первую очередь по влиянию их использования на прибыль.

Ряд задач требуют использования неоптимальных с точки зрения эстетики и уровня абстракции языков. Драйвера и embedded-приложения пишутся на C. Windows-приложения — на том, что поставляет в данный момент Microsoft (сейчас это C#). SAP кастомизируется с помощью ABAP, недалеко ушедшего в своем развитии от COBOL. Можете продолжать до бесконечности.

Кроме того, есть ниши, где выбор языка может повлиять на маркетинговую привлекательность продукта. Java продается. C# продается. Hashkell… — а что это такое? Думаю, логика выбора языка в таком случае будет очевидна.

Что думаете по этому поводу, коллеги?

Next Page »