- PVSM.RU - https://www.pvsm.ru -
Я знаю PHP. Не просто знаю, а действительно знаю. Не только синтаксис, или идиомы и особенности, но еще и почему — почему что-то работает именно так как оно работает, понимаете, под капотом. И скорее всего я тем или иным образом принимал участие в принятии того или иного решения. Все таки, тринадцать лет с языком — это долгий срок. Но я работал не только с PHP.
После двух лет своих занятий с PHP, я взял себе небольшой отпуск и выучил ColdFusion, который крутился поверх Java EE платформы. Собственно, поэтому я также поковырался в Java, так как ColdFusion можно расширять, используя Java компоненты.
Потом, естественно, было неизбежное погружение в JavaScript, приправленное порядочной порцией CSS, семантических Веб-технологий (RDF [1], OWL [2] и SPARQL [3]), XML, XPath и XSL (XSL:FO и XSLT), и не будем забывать про SQL. Черт, да я могу написать (и писал) DTD (Document Type Definition [4] — прим. переводчика)!
Не так давно, после того как я начал работать в EngineYard над платформой Orchestra PHP, я выучил Python. (Да, мы используем Python, для некоторых частей нашего PHP стека. Почему? Потому что это лучший инструмент для решения некоторых задач.)
Я не стал добавлять кучу ключевых слов в свое резюме, чтобы оно выглядело клево. Я решил так, потому что на данный момент, я считаю себя полиглотом.
Я всегда изучал новые инструменты (будь это демоны, утилиты, библиотеки, языки или сервисы) и судил их по нескольким критериям:
В конце концов, все сводится к тому, правильный ли это инструмент для решения поставленной задачи?
Именно поэтому, когда в конечно счете дело доходит до написания веб-сайтов, я выбираю именно PHP. Да познай свой инструмент хорошо, и да окупится тебе это сторицей!
Потом я пришел в EngineYard и познакомился с кучей потрясающих инженеров, которые выбрали для себя Ruby.
Даже сейчас, через более чем год работы в EngineYard, я узнаю что-то о Ruby или Rails. Конечно, я прочитал много кода на Ruby, в процессе code review, или просто из интереса, как что-то было реализовано. Я даже немного похачил Rails, но это было в основном скопировать-вставить-чуть_чуть_подкрутить.
Потом подоспел Distill [5], и нам понадобился сайт. Примерно 3 недели, чтобы все сделать, причем без отрыва от основных задач и без какой-либо спецификации на используемые технологии; в обычной ситуации я бы выбрал PHP и, вероятно, Zend Framework 2 [6], и сделал бы все за пару дней.
Вместо этого, учитывая мои обсуждения Distill и чего мы хотим достичь (с прицелом на решения, а не технологии) на ближайшие месяцы, я решил уцепиться за предоставившуюся возможность попробовать Rails (ну, и Ruby). Это был небольшой проект с ограниченным функционалом, к тому же я мог быстро откатиться к PHP, если бы встретил слишком много проблем с RoR. К счастью, окруженный, буквально, десятками потрясающих опытных разработчиков, я всегда мог найти человека, которому, я бы мог задать вопросы. Но, как Вы увидите далее, помощь мне не особенно и понадобилась.
Смысл данной статьи не в том, как я выучил Ruby или Rails, но в том, что я вынес из полученного опыта. Хотя, кое-что относительно RoR, тоже хотелось бы сказать.
После PHP, я определенно столкнулся с вещами, вызывающими WTF! реакцию:
if !<condition>
, if not <condition>
и unless <condition>
.
?
и !
, и есть соглашения, что методы с ?
на конце возвращают булево значение. Это не оператор. Это часть имена, например, foo.empty?
. Методы заканчивающиеся на !
обычно изменяют целевой объект, т.е. foo.downcase!
изменяет foo
, в то время как foo.downcase
просто возвращает результат, по этой причине такие методы в некотором смысле деструктивны.
В итоге, получаешь что-то вроде этого (реальный код на некотором этапе разработки сайта Distill, который возможно изменился к моменту запуска):
class Speaker < ActiveRecord::Base
belongs_to :user
has_many :proposals
attr_accessible :user, :bio, :email, :name, :id, :website, :photo
has_attached_file :photo, :styles => { :medium => "300x300>", :thumb => "120x120>" }
validates_attachment_content_type :photo, :content_type => /^image/(png|gif|jpeg)/
validates :bio, :email, :name, :photo, :presence => true
validates :email, :format => {
:with => /A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]+z/,
:message => "Must be a valid email address"
}
end
Пройдемся детально:
Speaker
, который наследуется (<
) от класса Base
в (::
) модуле ActiveRecord
.
end
).
«Подожди, вызовы методов, говоришь?»
Именно так!
«Это безумие! Мы же все еще в определении класса!»
(Нет, это Руби! ^_^ — прим. переводчика)
Во первых, важно отметить, что в Ruby неявный self
, который, как и self::
в PHP, вызывает методы статически (это самая простая аналогия). Это означает, что belongs_to :user
равнозначно self.belongs_to :user
. Что тут странно, так это то, что эти методы (которые, вообще говоря, наследованы) вызываются в процессе определения класса. Эти методы могут быть определены (например, def self.foo
) и вызваны (после определения) внутри определения того же самого класса, или унаследованы от его предка. Эти методы изменяют сам объект класса.
Ремарка: пока я писал этот пост, я наконец-то сам в полной мере осознал, что написано в предыдущем абзаце, и потвиттился с коллегой по EngineYard mkb [7], который помог всему этому уложится в голове; можете посмотреть тут [8] — вкратце: классы определяются в процессе исполнения кода, это означает, что можно программно определять классы, и даже работать с ними в процессе определения.
Таким образом, то, что я думал, является свойством (validates
), которое магически было определено дважды, на самом деле вызов метода — вспомните, я ранее упоминал про опциональность скобок при вызове метода. (Poetry mode это действительно очень удобно и красиво, но вспоминайте все же время от времени последние слова дяди Человека-Паука — «Большая сила — большая ответственность!» — прим. переводчика)
Ну, я сделал сайт. Безопасный, читаемый (код), приятный в использовании сайт. Не больше, чем я мог бы сделать с PHP, но было несколько вещей, которые просто снесли мне крышу.
Для большей части приложений мы имеем дело с обычным CRUD. Показать форму, принять данные, сохранить данные, показать их позднее. Не было сложных структур данных, о которых мне нужно было волноваться, или чего-нибудь еще такого. Ruby/Rails или PHP/Zend Framework 2 — да, без разницы. Вероятно, я бы даже на ***bash-скриптах*** смог бы все написать.
Я прочитал почти полностью Getting Started with Rails [9], адаптируя в процессе под свои нужны.
Я думал наиболее сложными будут следующие две вещи:
Чтобы решить данную проблему, я использовал отточенный временем навык гугления. В процессе, я наткнулся на Devise [10] и Omniauth [11]; два гема [12], которые реализовывали пользовательскую аутентификации и OAuth, соответственно.
Интегрировать эти гемы для человека, который едва знаком с Ruby или Rails, достаточно хитрая задача, но у меня получилось, и я, честно говоря, был шокирован. Они не просто разобрались с OAuth, но также позаботились о роутах, вьюхах, формах, схеме БД — в значительной степени обо всем. Мне пришлось написать собственные обработчики, чтобы записывать пользователей в базу и обрабатывать данные, полученные от сервисов (имя, email), но ничего слишком сложного.
И снова, с помощью Google, я нашел гем Paperclip [13]. Расширение для Active Record с файловыми вложениями.
С помощью Paperclip, даже не зная как реализовать загрузку файлов в Ruby/Rails, я смог решить поставленную задачу: сохранить различные подробности в базе, создать множественные миниатуры и загрузить все это в S3, и всего за несколько минут. По существу, после конфигурирования (которое включает в себя указание адаптера хранилища в S3, учетных данных и пути), и вызова rake, последующие несколько строчек решили все:
has_attached_file :photo, :styles => { :medium => "300x300>", :thumb => "120x120>" }
validates_attachment_content_type :photo, :content_type => /^image/(png|gif|jpeg)/
Тут мы называем вложение как «photo», указываем требуемые версии (300x300 и 120x120) и проверяем, что загружаются png, gif или jpeg.
Ну, мне по прежнему нужно многому научится. Ruby это не просто другой синтаксис, в отличии от моего опыта с Python. Я теперь, как говорится, чувствую, что могу разумно рассуждать о некоторых преимуществах Rails над его PHP-коллегами.
Одно из значительных преимуществ — это набор замечательных гемов, которые работают с Rails прямо из коробки, и могут привнести гораздо больше, чем средняя PHP библиотека, как из-за широкого распространения Rails с среде Ruby разработчиков, так и из-за того, что люди стараются придерживаться стандартизированного инструментария. Например, есть OAuth компонент для Zend Framework 2 [14], но он не предполагает, что вы используете ZF2 контроллеры/роутеры, и не прописывает соответсвующие роуты, как и не генерирует вьюхи, не встраивается в механизм аутентификации, не интегрируется с адаптером БД. Поэтому, как мне кажется, Rails (а следовательно и Ruby), замечательное средство для быстрой разработки. (Если Вы любите поохотиться на гемы, на The Ruby Toolbox [15] можно найти список гемов, отсортированных по сферам применениям и популярности, что довольно удобно!)
Я также думаю, что нужно отделять фреймворк от языка. Как PHP или Python, Ruby — это язык программирования общего назначения. Хотя PHP создавался с прицелом на работу в веб-окружении, это означает только, что он обеспечивает простой доступ к этому веб-окружению (GET/POST/Cookies, встроенная поддержка сессий, PUT/POST сырых данных, серверная среда, и т.д.) Для меня это значит только то, что я мог бы написать Distill на любом языке из трех упомянутых выше.
Один из основных факторов, почему PHP хорош для веба, это то, что его архитектура (Shared nothing architecture [16]) замечательно подходит для горизонтального масштабирования, и, похоже, лучше справляется с параллелизмом прямо из коробки — хотя Ruby движется семимильными шагами в этом направлении (с такими проектами, как rubinius и jruby). Это не означает, что Ruby или Python не могут или не хотят масштабироваться, просто, если посмотреть на кривую обучения, то точка, с которой Вы сможете делать это правильно, находится гораздо дальше. Конечно, работа с Engine Yard Cloud (в частности, для деплоя) избавила меня от этих проблем.
Итак, язык не так уж много значит, но что по поводу фреймворков? Смог бы я создать тот же самай веб-сайт, используя ZF2? Да. Было бы это проще? В некоторых моментах — да, учитывая, что я не так хорошо знаю Ruby и Rails. Однако я не думаю, что смог бы также быстро реализовать OAuth и подключить хранилище S3 при прочих равных. Теперь, возвращаясь к ZF2, я замечаю, что делаю гораздо больше рутины, такой как генерация форм, скелета, обновлений схемы, и т.д., как минимум, в самом начале процесса.
Означает ли это, что я перехожу на Ruby/Rails? Вряд ли. PHP все еще мой любимчик, хотя бы потому, что зная его так хорошо, я могу практически без усилий реализовывать свои идеи.
Вернусь ли я к Ruby/Rails снова? Возможно не для своих собственных проектов — я, как правило, работаю с друзьями из PHP сообщества. Но, при работе с моими замечательными коллегами из Engine Yard — непременно! Для меня, наиболее сильная черта Ruby/Rails, это сообщество, к знаниям которого я имею доступ. Вне зависимости от ответа на этот вопрос, изучение нового языка — и, что более важно, изучение лучших практик использования этого языка — надеюсь, делает меня лучшим разработчиком.
Это очень просто — зациклиться на языке, на сообществе, и думать, что мы учимся, потому что мы работаем на технологической периферии, с такими вещами как серверы баз данных, системы кеширования и веб-сервисы… и мы учимся, но как-то односторонне («The PHP Way» или «The Ruby Way»); смотрим на мир через шоры, ограничения, основанные на тех вещах, с которыми мы чувствуем себя комфортно.
Выходить из своей зоны комфорта — изучая новый язык — ключ к объединению всех наших технологий; именно воспринимая и обсуждая идеи с другими сообществами, мы улучшаем свой навык решения проблема — с использованием лучших решений, и лучших инструментов. Так что выбирайтесь на встречи или конференции, слушайте подкасты и читайте статьи про другие языки, даже если вы не заинтересованы в использовании этих языков.
Я очень доволен, что получилось наконец-то выделить достаточно времени на изучение новых замечательных инструментов и поработать над некоторыми изумительными технологиями с моими дорогими коллегами из Engine Yard, а также применить на практике основные идеи, которые я почерпнул в процессе своего путешествия в новую среду.
Автор: Deshene
Источник [17]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ruby/34076
Ссылки в тексте:
[1] RDF: http://www.w3.org/TR/REC-rdf-syntax/
[2] OWL: http://www.w3.org/TR/owl-features/
[3] SPARQL: http://www.w3.org/TR/rdf-sparql-query/
[4] Document Type Definition: http://ru.wikipedia.org/wiki/DTD
[5] Distill: http://distill.engineyard.com/
[6] Zend Framework 2: http://framework.zend.com/
[7] mkb: https://twitter.com/mkb
[8] тут: https://twitter.com/dshafik/status/308369397280559105
[9] Getting Started with Rails: http://guides.rubyonrails.org/getting_started.html
[10] Devise: https://github.com/plataformatec/devise
[11] Omniauth: https://github.com/intridea/omniauth
[12] гема: http://en.wikipedia.org/wiki/RubyGems
[13] Paperclip: https://github.com/thoughtbot/paperclip
[14] OAuth компонент для Zend Framework 2: https://github.com/zendframework/ZendOAuth
[15] The Ruby Toolbox: https://www.ruby-toolbox.com/
[16] Shared nothing architecture: http://en.wikipedia.org/wiki/Shared_nothing_architecture
[17] Источник: http://habrahabr.ru/post/179395/
Нажмите здесь для печати.