12 мая 2013 в 16:37

Изучая Rails (ну, и Ruby) перевод

Я знаю PHP. Не просто знаю, а действительно знаю. Не только синтаксис, или идиомы и особенности, но еще и почему — почему что-то работает именно так как оно работает, понимаете, под капотом. И скорее всего я тем или иным образом принимал участие в принятии того или иного решения. Все таки, тринадцать лет с языком — это долгий срок. Но я работал не только с PHP.


После двух лет своих занятий с PHP, я взял себе небольшой отпуск и выучил ColdFusion, который крутился поверх Java EE платформы. Собственно, поэтому я также поковырался в Java, так как ColdFusion можно расширять, используя Java компоненты.

Потом, естественно, было неизбежное погружение в JavaScript, приправленное порядочной порцией CSS, семантических Веб-технологий (RDF, OWL и SPARQL), XML, XPath и XSL (XSL:FO и XSLT), и не будем забывать про SQL. Черт, да я могу написать (и писал) DTD (Document Type Definitionприм. переводчика)!

Не так давно, после того как я начал работать в EngineYard над платформой Orchestra PHP, я выучил Python. (Да, мы используем Python, для некоторых частей нашего PHP стека. Почему? Потому что это лучший инструмент для решения некоторых задач.)

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

Я всегда изучал новые инструменты (будь это демоны, утилиты, библиотеки, языки или сервисы) и судил их по нескольким критериям:
  • Насколько хорошо инструмент написан?
  • Что у него с безопасностью?
  • Сколько в нем открытых багов?
  • Как реагировало сообщество на предыдущие проблемы (были ли они [члены сообщества] отрыты, дружелюбны, вежливы, оперативны)?
  • Достаточен ли функционал для решения моих проблем?
  • Не слишком ли избыточен функционал для решения моих проблем?

В конце концов, все сводится к тому, правильный ли это инструмент для решения поставленной задачи?

Именно поэтому, когда в конечном счете дело доходит до написания веб-сайтов, я выбираю именно PHP. Да познай свой инструмент хорошо, и да окупится тебе это сторицей!

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

Даже сейчас, через более чем год работы в EngineYard, я узнаю что-то о Ruby или Rails. Конечно, я прочитал много кода на Ruby, в процессе code review, или просто из интереса, как что-то было реализовано. Я даже немного похачил Rails, но это было в основном скопировать-вставить-чуть_чуть_подкрутить.

Потом подоспел Distill, и нам понадобился сайт. Примерно 3 недели, чтобы все сделать, причем без отрыва от основных задач и без какой-либо спецификации на используемые технологии; в обычной ситуации я бы выбрал PHP и, вероятно, Zend Framework 2, и сделал бы все за пару дней.

Вместо этого, учитывая мои обсуждения Distill и чего мы хотим достичь (с прицелом на решения, а не технологии) на ближайшие месяцы, я решил уцепиться за предоставившуюся возможность попробовать Rails (ну, и Ruby). Это был небольшой проект с ограниченным функционалом, к тому же я мог быстро откатиться к PHP, если бы встретил слишком много проблем с RoR. К счастью, окруженный, буквально, десятками потрясающих опытных разработчиков, я всегда мог найти человека, которому, я бы мог задать вопросы. Но, как Вы увидите далее, помощь мне не особенно и понадобилась.

Детали реализации


Смысл данной статьи не в том, как я выучил Ruby или Rails, но в том, что я вынес из полученного опыта. Хотя, кое-что относительно RoR, тоже хотелось бы сказать.

После PHP, я определенно столкнулся с вещами, вызывающими WTF! реакцию:
  • Скобки опциональны при вызове метода и часто не используются, однако в некоторых случаях (например, вложенные вызовы) они нужны.
  • Очень много вариантов «if not». Например: 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

Пройдемся детально:
  • Строка 1: Мы определяем класс Speaker, который наследуется (<) от класса Base в (::) модуле ActiveRecord.
  • Строки 2, 3, 5, 7, 8, 9, 10: все это вызовы методов.
  • Строка 15: закрываем определение класса (end).

«Подожди, вызовы методов, говоришь?»
Именно так!
«Это безумие! Мы же все еще в определении класса!»
(Нет, это Руби! ^_^ — прим. переводчика)

Во первых, важно отметить, что в Ruby неявный self, который, как и self:: в PHP, вызывает методы статически (это самая простая аналогия). Это означает, что belongs_to :user равнозначно self.belongs_to :user. Что тут странно, так это то, что эти методы (которые, вообще говоря, наследованы) вызываются в процессе определения класса. Эти методы могут быть определены (например, def self.foo) и вызваны (после определения) внутри определения того же самого класса, или унаследованы от его предка. Эти методы изменяют сам объект класса.

Ремарка: пока я писал этот пост, я наконец-то сам в полной мере осознал, что написано в предыдущем абзаце, и потвиттился с коллегой по EngineYard mkb, который помог всему этому уложится в голове; можете посмотреть тут — вкратце: классы определяются в процессе исполнения кода, это означает, что можно программно определять классы, и даже работать с ними в процессе определения.

Таким образом, то, что я думал, является свойством (validates), которое магически было определено дважды, на самом деле вызов метода — вспомните, я ранее упоминал про опциональность скобок при вызове метода. (Poetry mode это действительно очень удобно и красиво, но вспоминайте все же время от времени последние слова дяди Человека-Паука — «Большая сила — большая ответственность!» — прим. переводчика)

И что получилось?


Ну, я сделал сайт. Безопасный, читаемый (код), приятный в использовании сайт. Не больше, чем я мог бы сделать с PHP, но было несколько вещей, которые просто снесли мне крышу.

Для большей части приложений мы имеем дело с обычным CRUD. Показать форму, принять данные, сохранить данные, показать их позднее. Не было сложных структур данных, о которых мне нужно было волноваться, или чего-нибудь еще такого. Ruby/Rails или PHP/Zend Framework 2 — да, без разницы. Вероятно, я бы даже на ***bash-скриптах*** смог бы все написать.

Я прочитал почти полностью Getting Started with Rails, адаптируя в процессе под свои нужны.

Я думал наиболее сложными будут следующие две вещи:
  1. OAuth с разными провайдерами (Github, Facebook и Twitter).
  2. Хранение загруженных изображений в S3.

OAuth с разными провайдерами


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

Интегрировать эти гемы для человека, который едва знаком с Ruby или Rails, достаточно хитрая задача, но у меня получилось, и я, честно говоря, был шокирован. Они не просто разобрались с OAuth, но также позаботились о роутах, вьюхах, формах, схеме БД — в значительной степени обо всем. Мне пришлось написать собственные обработчики, чтобы записывать пользователей в базу и обрабатывать данные, полученные от сервисов (имя, email), но ничего слишком сложного.

Загрузка изображений в S3


И снова, с помощью Google, я нашел гем Paperclip. Расширение для 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, но он не предполагает, что вы используете ZF2 контроллеры/роутеры, и не прописывает соответсвующие роуты, как и не генерирует вьюхи, не встраивается в механизм аутентификации, не интегрируется с адаптером БД. Поэтому, как мне кажется, Rails (а следовательно и Ruby), замечательное средство для быстрой разработки. (Если Вы любите поохотиться на гемы, на The Ruby Toolbox можно найти список гемов, отсортированных по сферам применениям и популярности, что довольно удобно!)

Я также думаю, что нужно отделять фреймворк от языка. Как PHP или Python, Ruby — это язык программирования общего назначения. Хотя PHP создавался с прицелом на работу в веб-окружении, это означает только, что он обеспечивает простой доступ к этому веб-окружению (GET/POST/Cookies, встроенная поддержка сессий, PUT/POST сырых данных, серверная среда, и т.д.) Для меня это значит только то, что я мог бы написать Distill на любом языке из трех упомянутых выше.

Один из основных факторов, почему PHP хорош для веба, это то, что его архитектура (Shared nothing architecture) замечательно подходит для горизонтального масштабирования, и, похоже, лучше справляется с параллелизмом прямо из коробки — хотя 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, а также применить на практике основные идеи, которые я почерпнул в процессе своего путешествия в новую среду.
Как часто Вы тратите время на изучение новых языков, технологий, практик, не связанных с Вашими основными обязанностями?

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Проголосовало 1329 человек. Воздержалось 223 человека.

+33
39638
185
Deshene 8,5

Комментарии (53)

+19
maxp #
После 13-и лет (!) ковыряния в одном языке (PHP тут не при чем, хотя и показатель) человек вдруг увидел другой мир. Мои поздравления, теперь можно развиваться дальше.

В опроснике не хватает самого главного пункта — «Я изучаю новое постоянно. Без этого я мертв, как ИТ профессионал.»

Именно, не «модные штуки», а просто «жизненно важное».
+5
MrLoki #
Вроде статья почти без картинок, а вы всё равно на что-то отвлеклись.

В начале:
>Я всегда изучал новые инструменты (будь это демоны, утилиты, библиотеки, языки или сервисы)

И в конце:
>Выходить из своей зоны комфорта — изучая новый язык — ключ к объединению всех наших технологий; именно воспринимая и обсуждая идеи с другими сообществами, мы улучшаем свой навык решения проблем — с использованием лучших решений, и лучших инструментов. Так что выбирайтесь на встречи или конференции, слушайте подкасты и читайте статьи про другие языки, даже если вы не заинтересованы в использовании этих языков.
+2
Deshene #
Ну, если быть чуть более точным, во втором абзаце автор упоминает, что после пары лет ковыряния PHP он решил открыть для себя дивный новый мир с ColdFusion, Java, Javascript, etc. Другое дело, что PHP является его основным языком последние 13 лет.
–5
maxp #
Автор пишет «Все таки, тринадцать лет с языком — это долгий срок». И судя по статье ознакомиться, например, с экосистемой Java достаточно глубоко ему не удалось.

Нет, я ничего не имею против откровений «смотрите, при описании класса выполняется код с self», понимание это очень даже здорово и правильно. Даже если оно случается после стольких лет.

Просто на мой субъективный взгляд, те принципы, которые используются в большинстве популярных языков программирования, не плохо было бы осваивать в первые год-два актавной работы. Иначе это анабиоз какой-то.
0
TyVik #
В точку! Но изучение чего-то нового без конкретной задачи по крайней мере для меня тяжеловато. Ну прочитаешь умную книжку, а без практики всё забудется. Стараюсь сначала придумать что-нибудь интересненькое, а потом это реализовать на новом для себя языке/фреймворке, прям как автор. А потом ещё выложить на github, чтоб можно было подсматривать.
0
dotme #
Согласен с вами в вопросе работы с конкретными задачами. Лично мне часто становиться лень придумывать себе задания (хотя у меня всегда есть пара любимых алгоритмов), а познакомиться с языком или технологией очень часто хочеться здесь и сейчас.

Для себя нашел, пусть и не лучший вариант для изучения языка, но отличный способ знакомства и понимания его идеологии, а так же возможности небольшой практический опыт получить, не устанавливая кучу левого софта на машину или несколько разных машин, если пытаться заниматься и дома и на работе и еще в куче мест — тут хоть и не большой выбор технологий, но для некоторого знакомства вполне хватает. Думаю подобных проектов десятки, мне еще по душе эта площадка, но она платная.
+1
kaichou #
После 13-и лет (!) ковыряния в одном языке (PHP тут не при чем, хотя и показатель) человек вдруг увидел другой мир. Мои поздравления, теперь можно развиваться дальше.

Боюсь представить, как вы оцените первоклассных специалистов, которые 20 лет на с++ пишут. Скажете, что они не развиваются?

За 13 лет php прошёл долгий путь развития, и всё сообщество вслед за ним.
99% опытных пхпшников серьёзно пробовали и питон, и руби. И у всех, кого знаю, реакция как у автора статьи: «Означает ли это, что я перехожу на Ruby/Rails? Вряд ли. PHP все еще мой любимчик»
+6
azverin #
От статьи двоякое ощущение: с одной стороны, общая мысль правильная, изучайте то, что есть вокруг, не зацикливайтесь на одном инструменте.

С другой, примеры выбранные автором ниразу не мотивируют:
— Выбор РоР для проекта не обоснован и не раскрывает преимуществ РоР перед PHP.
— Пример кода сбивает с толку, т.к. совершенно нечитабельно то, что происходит (с точки зрения синтаксиса PHPшника). Возможность писать не так как обычно могла бы быть плюсом к ФП, но не здесь.

даже не зная как реализовать загрузку файлов в Ruby/Rails, я смог решить поставленную задачу

Радость от использования готовых гемов — аналогично когда человек вешает джумлу, у него получается сделать стандартные штуки типа регистрации или отправки сообщения и он со штанами полными радости кричит: «о дааа, теперь я знаю похапэ и могу о нем рассказывать неофитам»!

Лично я чувствую дискомфорт, когда я не понимаю как что-то работает. Потому что когда понадобится сделать что-то нестандартное, всё джедайство сразу сдуется.
+6
hazg #
RoR привлекает как раз читабельностью, ИМХО. Примеры очевидны, для англоязычной аудитории. Чем плох нативный язык?

Оратор < Запись:: Базовая
принадлежит: пользователю
имеет_много: предположений

хеши? Они не плохие в руби.

Много сахара. Rails way действительно надо понимать, а руби знать — разве с другими языками\фреймворками по другому?

>> РоР перед PHP
Ror c фреймворком на php лучше сравнивать, а php — c ruby.
–1
azverin #
У меня неплохой английский — не стоит из руби делать 1С ;) Про непонятность говорится в тексте:

Что тут странно, так это то, что эти методы (которые, вообще говоря, наследованы) вызываются в процессе определения класса.

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

Ror c фреймворком на php лучше сравнивать, а php — c ruby.

Да, в целом, это более корректная постановка вопроса.

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

Странно переходить с PHP на Ruby и писать потом (условно) hello-world-блог, т.к. преимуществ явных от этого не получится.
+1
sl_bug #
> где объявляется

примерно в ActiveRecord::Base от которого наследуемся.

> что вызывается

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

> почему вызвается не там, где привычно это видеть

почему не там? в руби можно вызывать методы где угодно. можно было бы сделать и в конструкторе, но зачем если так проще?
–1
azverin #
Это не было вопросом, тем более в статье всё разжевано. Речь о том, что пример кода неуместный в данном контексте.
0
sl_bug #
Пример показал то, что в статье разжевано. Значит цель достигнута
+3
Lovesuper #
Я когда с PHP перешел на Python (после года активного программирования на первом) — был поражен открывшимся возможностями нового для меня языка, вот честно, наповал поражен! Мне кажется, нельзя просто взять и выбрать для себя язык на все времена. Всегда есть вариант, что Вы найдете то, что Вам нужно там, где даже не думали искать.
0
m_z #
А можно топ список вещей, которыми были поражены? :) Я понимаю восторг от перехода на компилируемые, строготипизированные языки, языки с другой парадигмой или экзотическим синтаксисом, но разницу между python и php я не заметил (конечно же, не считая продуманности и лучшей архитектуры первого).
+5
Lovesuper #
О, мой Бог! Конечно! Первое, что мне очень понравилось — это очаровательный синтаксис. Он такой прекрасный, что может даже сойти за псевдокод (чего только стоят инлайновые конструкции). Потом мне очень понравилась объектная система, наследоваться стало проще, а само наследование оказалось прозрачным. Затем следует прекрасно расширяемый полиморфизм. Python задуман, чтобы отвечать принципу Утиной Типизации. Следом идет наличие байт-кода (без комментариев). Потом шествует огромное комьюнити с широкой документацией любых модулей. Далее идет конечно модульность (опять же без комментариев). Да много там всего… Повторюсь, я год писал на пыхе — ну вообще она ни в какие сравнения не идет с пайтоном. Простите меня, за такой холивар.
0
SowingSadness #
Не стал бы я относить утиную типизацию к плюсам языка.
–4
Lovesuper #
А я бы Вас не стал относить к специалистам.
+1
Zelgadis #
Одна из основных фич Go-lang для меня. Так, что оратор выше прав — не понимаете разницу между различными видами типизации.
0
Fally #
>> Потом мне очень понравилась объектная система, наследоваться стало проще, а само наследование оказалось прозрачным
Я может конечно Питон не так хорошо помню, но чем же, скажите на милось, различаются объектные системы пхп и питона?

>> Затем следует прекрасно расширяемый полиморфизм.
Подробнее можете? Я не очень понимаю, что вы этим хотели сказать.

>> Следом идет наличие байт-кода (без комментариев).
Это вы про *.pyc, которые после первого запуска формируются? По секрету, в рхр тоже есть байткод, но для его хэширования нужно использовать отдельные модули: APC, eAccelerator

>> принципу Утиной Типизации
Самое ужасное, как мне кажется, что может быть, это когда два объекта одного класса имеют разный набор методов и пр. Удобно? Вполне возможно. Поддерживаемо через 6-12 месяцев? Сомневаюсь.

>> Потом шествует огромное комьюнити с широкой документацией любых модулей.
Ага, а PHP со своей докой и бОльшим сообществом нервно курит в сторонке ;)
+1
Deshene #
>>принципу Утиной Типизации
Самое ужасное, как мне кажется, что может быть, это когда два объекта одного класса имеют разный набор методов и пр. Удобно? Вполне возможно. Поддерживаемо через 6-12 месяцев? Сомневаюсь.

Непонятно причем здесь два объекта одного класса и разный набор методов. Та утиная типизация, о которой я знаю, выражается в следующем предложении: "Если объект ходит как утка, и крякает как утка, значит он — утка."
Т.е. мы судим по объекту на основании поведения объекта (поддерживаемым методам), а не по его генеалогическому древу (наследование класса/реализация интерфейса). Т.е. если у объекта есть метод [], мы можем работать с ним, как с массивом, хотя это совсем необязательно массив. В целом утиная типизация это скорее соглашение, и следовать этому соглашению можно как при написании кода на PHP, так и на Python или Ruby. Другое дело, что одни языки больше располагают к этому, а другие — меньше.
–2
Lovesuper #
«Не очень хорошо помню»? т.е. Вы знали Питон? и потом начали пыхать? Вот Вам отличия модели Питона ссылка. Ваши доводы абсолютно профанские. Чего только стоит то, что на Пайтоне можно реализовать любую системную программу, параллельные вычисления, веб. А на пыхе что? Только сайты(ики). На счет байт-кода в пхп — это пляски с бубном. А пляски — ничего хорошего, по сравнению с нативной поддержкой. На счет поддержки через полгода: нет ничего лучше, чем не задумываться какого типа должны быть аргументы — просто итератор какой-то, например. Ошибка TypeError теперь будет свидетельствовать о реальном несоответствии типов, а не то что я передал «111» вместо 111(пример такой). А на счет последнего — зрз с его укуренной документацией, непонятным методом обзывания функций и огромным комьюнити школоразработчиков сайтов вот уж и правда курят в стороне. А что курят-то?
+2
VolCh #
В PHP по умолчанию как раз утиная типизация, выражение $obj->method() будет проверять наличие meyhod() непосредственно при исполнении и не требует объявления $obj как экземпляра какого-то класса или реализации интерфейса — есть метод, значит можем его вызвать (а иногда можем и если его нет)… Плюс на уровне синтаксиса поддерживается (не всегда хорошо) поведение «кастомных» объектов как «скаляров» (если объект имплементирует каккой-то из predefined interfaces, то сни можно обращаться как соответствующей сущностью)
+5
nwalker #
Невероятно прекрасная на фоне PHP модель данных.
Шикарная на фоне PHP модульность.
Нормальные замыкания, декораторы, элементы ФП.
Классы как first class object, метаклассы, дескрипторы.
Человеческий синтаксис в конце концов.

По-моему, этого уже достаточно, чтобы один раз попробовав Python пожелать никогда не возвращаться к PHP.
+2
Zelgadis #
Какие же замыкания тогда в PHP если вам python этим понравился?
+1
nwalker #
А в тот момент их не было вообще. А в нынешних я считаю костылем указание замыкаемых переменных. Кстати, а ПХП переменные затягивает в замыкание по ссылке или по значению?
Да, замыкания в Питоне не идеал, но это было мое первое с ними знакомство — простительно, думаю.
+2
Deshene #
Ну, костыль не костыль, но Вы уверены, что Вам всегда нужно таскать в замыкание весь контекст? А если нужно, то возможно Вы что-то делаете не так?
Ну, и к тому же, один из пунктов философии Python, если мне не изменяет память — «Явное лучше, чем неявное» ;)
0
nwalker #
А вы уверены, что там весь контекст захватывается? Я вот думаю, что только referenced переменные. См. repl.it/Ivl
0
Deshene #
Да, судя по всему, Вы правы. Вопрос снимается.
+1
artyfarty #
Кстати, а ПХП переменные затягивает в замыкание по ссылке или по значению?

Как передадите. По умолчанию — по значению. Если с амперсандом — то по ссылке.
+1
Pe4enie #
А теперь попробуйте RoR, будете поражены ещё раз.
+5
Lovesuper #
Не путайте язык с произведением.
+3
guessss_who #
Вы работали с Django? (спрашиваю, т.к. в таком случае мне были бы особо интересны ваши аргументы в пользу RoR).
–3
Lovesuper #
Да, я сейчас делаю проект на Джанго. У меня нет аргументов в ползу Рельс. У меня вообще нет никакого отношения к рельсам, ибо не знаю их at all. А про язык и произведение нужно понимать в общелитературном ключе.
0
guessss_who #
Вопрос был к Pe4enie. :)
0
VolCh #
Немного работал и с тем, и с другим, RoR нравится больше. Но это именно «нравится». Кому-то нравится «магия», а кому-то «явное лучше неявного».
0
guessss_who #
RoR это «магия»?
+1
VolCh #
Ага ::)
+1
roller #
Лол) Ctrl-клик перенесет вас к источнику магии, то бишь к исходникам
–1
VolCh #
От того, что у магии есть источник, она ею не перестает быть :)
+2
XimikS #
На самом деле, это светлая магия.
В джанго всё явно, но многое пришлось делать ручками. Я когда открыл для себя RoR, то прифигел от концепции гемов и легкости их установки и настройки. А после какого-то момента понял, что и магии то нету, а продуманность соглашений и ускорение работы разработчика.
+1
VolCh #
Никто же не говорит, что она темная как на Perl :)

+1
sanzstez #
Paperclip это конечно гуд, но есть хорошая альтернатива Сarrierwave github.com/jnicklas/carrierwave. S3, Google Storage, кроп изображений + возможность перехода с paperclip.
+1
Weageoo #
можно программно определять классы

Так динамический язык же.

Python:

TestClass = type('TestClass', (object,), dict(value = 1, get_value = lambda self: self.value))
print TestClass().get_value()

или

def init(self, value):
	self.value = value
	
String = type('String', (object,), {})
String.__init__ = init
String.reverse = lambda self: self.value[::-1]

print String('Hello, world!').reverse()

del String.reverse # remove method definition

Конечно, следует предпочитать явное определение типа его динамическому аналогу.
+1
kpuzuc #
Я уверен, что для PHP есть уже готовая библиотека для работы с OAuth (ищем на гитхабе).

Код в примере немногословен, да, но я тоже самое могу сделать на PHP. Лучше бы была показана реализация любой стандартной вещи, например CRUD.

В статье вижу только восторг автора, каких-то ключевых особенностей Ruby/RoR в статье я не заметил (кроме синтаксиса).
+1
Kane #
Я знаю PHP. Не просто знаю, а действительно знаю. Не только синтаксис, или идиомы и особенности, но еще и почему — почему что-то работает именно так как оно работает, понимаете, под капотом.

Почему str_split, но strlen и parse_str?
+2
int03e #
Вот в чем еще плюс руби — нет такой путаницы в наименованиях, стандартная библиотека красивая и логичная :)
0
Deshene #
ИМХО, потому что сначала организоваться не сумели, а потом БАХ!, и уже столько легаси, что менять что-то уже поздно.
+2
Insa88 #
Ключевая мысль статьи — у ruby много правильных гемов. Если PHP обладал бы единственным фреймворком (я знаю, что у ruby он не один, но 99% используют RoR) на который все ориентировались и писали бы библиотеки под него, да еще и стандартизировали их, то в чем разница? Представьте если всё PHP сообщество вдруг пересядет скажем на yii2 и начнет писать extensions только под него, что из этого выйдет, у кого х** окажется длинней, сайты быстрей, а разработка короче?
0
spaceblock #
хорошо сказано)
+2
rinat_crone #
Вы забываете о том, что гемы в руби можно использовать не только с рельсами, так что ваша пэхепешная аналогия здесь не совсем к месту. Я могу писать консольную утилиту на руби и спокойно подключить к ней пару-тройку необходимых гемов. Сможете ли вы к стороннему PHP-скрипту подключить библиотеку от yii2 даже если их будет миллион?

Также, Вы очень сильно заблуждаетесь относительно процентов использования RoR в применении к руби-программистам. Для некоторых задач используется Sinatra и ему подобные фреймворки, а для других – (omg, кто бы мог подумать!) вообще не используются веб-фреймворки.

У Вас, как и у многих людей в этом треде, проблема с пониманием того, что такое руби и что такое рельсы. Я не упрекаю Вас в этом, прошу лишь разобраться в вопросе более подробно, если хотите давать кому-нибудь объективные рекомендации по этому поводу.
–1
VolCh #
Сможете ли вы к стороннему PHP-скрипту подключить библиотеку от yii2 даже если их будет миллион?

Насчёт Yii не скажу, но PEAR существует наверное столько же сколько сам PHP. Плюс за последнее время набирает популярность composer (более близкий по идеологии к gem) и там не составит труда подключить что угодно к чему угодно. Если кто-то позаботился о пакете в паблике, то и зависимости разрулятся. Если нет то зависимости нужно будет прописать ручками если в, например, гит-репе нужный модуль без зависимостей.
–1
Insa88 #
И с чего вы взяли, что у меня проблемы с пониманием что такое ruby и рельсы? Вот у вас точно проблемы с пониманием PHP, но вам это не мешает давать «кому-нибудь объективные рекомендации». У ruby так же немало гемов, которые ориентированы исключительно на рельсы, а другие независимые — у PHP так же, и большая проблема PHP это огромнейшее кол-во разрозненных решений, которые между собой могут не интегрироваться, а есть такие которые могут интегрироваться почти всегда (вам выше уже ответили). И omg, кто бы мог подумать, что у PHP огромное кол-во проектов, которые не используют фрейморки. Сейчас руби быстро набирает популярность и в его сообществе так же появится большая каша из кода несовместимого между собой — подождите и у вас все будет.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.