Статьи

Признания преобразованного разработчика PHP: Гадкий код

Я был разработчиком PHP почти десять лет, и в январе этого года я начал разрабатывать в Ruby. Хотя изначально я был скептиком, я теперь новообращенный, и я здесь, чтобы поделиться с вами своим опытом. Я далёк от того, чтобы претендовать на звание разработчика оружия Rails; Я новичок в Rails, и я хочу написать это. Я не могу назвать все официальным именем, но вы поймете суть.

Идея изменения часто может быть страшной. Переход на новый язык из безопасности языка, который вы знаете и которому доверяете, не должен быть легким. Я хотел бы думать о себе как о достаточно хорошем PHP-разработчике, и идея перехода на Rails была и пугающей, и захватывающей. Я сделал решающий шаг из-за нового веб-сайта, который мы разработали на работе, и теперь я могу с уверенностью сказать, что я перешел на Ruby. Язык и структура Ruby прекрасны, а скорость разработки, которую обеспечивает Rails, делает мою жизнь намного проще.

Это был непростой переход. Мои коллеги могут засвидетельствовать, что я несколько дней ругался на своем ноутбуке в отчаянии, обычно пытаясь выполнять простые задачи. В защиту Руби, это разочарования, которые хорошо компенсируются восхищением выяснением того, как легко делать другие вещи — и любой учебный процесс имеет свои разочарования. Мне достаточно легко об этом говорить, но давайте рассмотрим реальный пример.

Рубин: объективированный

Все в Ruby это объект. Все. Даже ничто не является объектом; nil является экземпляром NilClass. Это означает, что вместо процедурного «вложения» или бесконечного создания переменных, которые вам придется выполнять в PHP, вы можете просто связывать вызовы методов при работе с переменными любого типа. «О, это здорово, но что это значит для меня?» Я слышу, вы спрашиваете. Ну, продолжайте читать.

Скажем, у меня есть строка адресов электронной почты, разделенных запятыми, и я хочу получить список всех уникальных доменных имен из этой строки. Это превратилось бы в довольно существенный процесс в PHP:

<?php
  // Our list of emails
  $string = "[email protected], [email protected], [email protected]";
  &nbsp;
  // Explode into an array of emails
  $emails = explode(', ', $string);
  &nbsp;
  // Create a function to remove anything which isn’t the domain portion of the email
  $leave_domain = function($subject){
      return preg_replace("/^(.*)@/","", $subject);
  };
  &nbsp;
  // Apply the function we just created to the emails array
  $domains = array_map($leave_domain, $emails);
  &nbsp;
  // Remove any repeated domains
  $unique_domains = array_unique($domains);
  &nbsp;
  print_r($unique_domains);
?>

Что дает нам:

 Array
(
    [0] => sitepoint.com
    [1] => learnable.com
)

Итак, я начинаю с разрыва нашей строки в массив; затем я сопоставляю функцию, которая заменяет все, кроме доменной части письма, гарантируя, что у нас есть только уникальные значения.

Примечание: я использовал анонимную функцию для вызова array_map Это будет работать только в PHP 5.3. Вы можете использовать цикл foreach

Это довольно много кода для простой концепции. Вы можете объединить все это в одну команду, вложив функции; однако это будет стоить читабельности:

 <?php
  $string = "[email protected], [email protected], [email protected]";
  &nbsp;
  $unique_domains = array_unique( array_map( function($subject){ return preg_replace("/^(.*)@/","", $subject); }, explode(', ', $string)));
?>

Теперь это чертовски уродливый код. Попробуйте объяснить это кому-то, не причиняя ему головной боли! Основная проблема здесь заключается в том, что он должен быть вложенным и терять читаемость или содержать настоящую группу переменных, чтобы отделить каждую часть процесса.

В Ruby, поскольку все является объектом, мы можем связывать вызовы функций вместе:

 string = "[email protected], [email protected], [email protected]"
unique_domains = string.split(', ').map{ |e| e.gsub(/^(.*)@/,'') }.uniq

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

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

Это одно из фундаментальных отличий между Ruby и PHP и одна из причин, по которым Ruby является таким замечательным языком для работы.

Будет ли это работать?

Одно из самых больших разочарований, которые я испытывал при изучении Ruby, — это мое полное отсутствие знаний о том, какие функции доступны, а также их точные спецификации или требования. Когда я изучал PHP, мне было проще всего понять это путем написания кода; то есть методом проб и ошибок. Это была довольно трудоемкая задача, и она действительно является эффективным способом кодирования.

После того, как вы установили Ruby, вы получите доступ к замечательной интерактивной оболочке Ruby или IRB для краткости. Любой, кто изучал Ruby, скорее всего, слышал об этом, но вы можете не осознавать, насколько он чертовски полезен. Это место по умолчанию, куда вы идете, чтобы ответить на ваши простые вопросы «Будет ли это работать?». Вы можете легко подключиться к сеансу IRB, набрав в консоли магические три буквы `irb`, и вы попадете в командную строку. Здесь вы можете делать все, что делаете в обычном Ruby-скрипте, по одной строке за раз. Если что-то пойдет не так, просто нажмите «вверх» и исправьте свою проблему! В PHP нет ничего подобного, поэтому это новая концепция для большинства разработчиков PHP.

При написании приведенных выше примеров я использовал IRB, чтобы убедиться в правильности синтаксиса. Я начал новый сеанс IRB и установил строковую переменную:

 irb > emails = "[email protected], [email protected], [email protected]"
 => "[email protected], [email protected], [email protected]"

Первая часть здесь, вплоть до>, это просто мое приглашение IRB. Затем я установил переменную `emails` в строку, нажал клавишу ввода, и IRB вывел ответ предыдущей строки; это просто говорит мне, что это строка.

Следующим моим действием было разделить строку на электронные письма и заменить часть имени в строке электронного письма:

 irb > emails.split(', ').gsub(/^(.*)@/,'')
NoMethodError: undefined method `gsub' for ["[email protected]", "[email protected]", "[email protected]"]:Array

Здесь произошло две вещи. Во-первых, я использую переменную, которую я создал ранее, и это хорошо — это доступно для этой сессии. Во-вторых, я запустил split для строковой переменной, а затем попробовал метод gsub.

Впоследствии, Ruby правильно и корректно изобразил ошибку: gsub Вам нужно запустить gsub К счастью, у массивов есть функция, которая может мне помочь: map Функция map берет блок и запускает его на каждом из элементов в массиве.

 irb > unique_domains = emails.split(', ').map{ |e| e.gsub(/^(.*)@/,'')}
 => ["sitepoint.com", "learnable.com", "sitepoint.com"]

Вуаля! Используя значение карты, мы правильно создали массив, содержащий только домены, которые были в адресах электронной почты. Оттуда было достаточно легко добавить метод uniq и boom — уникальные домены из цепочки адресов электронной почты.

Сделав это через IRB, я смог легко увидеть ответы на мои вопросы «Будет ли это работать?» И отлаживать код до тех пор, пока он не сделал.

Примечание: блоки это круто. Это одна из замечательных возможностей Ruby, потому что они мощные и гибкие, но они выходят за рамки того, о чем я говорю. Я расскажу о блоках в следующем блоге на этом сайте, поэтому, если вы еще о них не знаете, следите за обновлениями на RubySource.

Если вы хотите протестировать код, специфичный для Rails, вы можете использовать консоль Rails; это аналогично, за исключением того, что загружает всю среду Rails. В окне консоли убедитесь, что вы находитесь в каталоге проекта Rails, и наберите `rails console` или псевдоним` rails c`. Загрузка займет секунду, но как только вы войдете, у вас будет доступ ко всем моделям вашего проекта, помощникам и т. Д. В среде Rails.

 mal@mal:~/my/rails/project$ rails c
Loading development environment (Rails 3.0.5)
ruby-1.9.2-p180 :001 >

Это всего лишь один совет, который я хотел бы начать в Ruby с PHP. У меня есть еще несколько в моем рукаве. Вы недавно начали в Ruby или Rails? Если да, то какими советами вы можете поделиться?