Комментарии 349
> Лучшая поддержка работы со временем и датой.
> Стандартная библиотека Python даже с UTC не позволяет работать.
Вам больше нечего добавить по этому поводу? :) Pytz — стандарт де-факто, который по разумным соображениям не входит в дистрибутив самого питона, но в легкую ставится отдельно.
> Стандартная библиотека Python даже с UTC не позволяет работать.
Вам больше нечего добавить по этому поводу? :) Pytz — стандарт де-факто, который по разумным соображениям не входит в дистрибутив самого питона, но в легкую ставится отдельно.
Как уже говорилось, я не рассматриваю сторонние библиотеки. В общем случае на компьютере, где мы используем скрипты, может не стоять ничего кроме стандартной поставки, а установка сторонних библиотек может быть затруднительна — конфликты, sudo и прочее.
#!/usr/bin/env python
import datetime
datetime.datetime.utcnow()
Вы просто UTC не умеете готовить :)
import datetime
datetime.datetime.utcnow()
Вы просто UTC не умеете готовить :)
А где все. Где холивары.
Все опасливо смотрят на карму и не рискуют.
Зато когда в erlang пишут — наши процессы это не те процессы которые ОС, а полностью контролируются виртуальной машиной erlang — это ого-го :)
ОС работает в режиме ядра, а пользовательскому приложению туда хода нет, поэтому программная эмуляция параллелизма без использования потоков ОС всегда будет сложнее и медленнее.
Нет никакой магии, просто такова архитектура современной связки компьютер-ОС.
Современные процессоры имеют режим ядра, в котором работает ОС, но пользовательские программы получить к нему доступ не могут иначе как средствами ОС. Таким пользовательская программе непрямую недоступны некоторые инструменты процессора, которые в могут в значительной мере оптимизировать в том числе и параллелизм.
Собственно поэтому и Ruby так же пошли по этому пути в новой версии.
Современные процессоры имеют режим ядра, в котором работает ОС, но пользовательские программы получить к нему доступ не могут иначе как средствами ОС. Таким пользовательская программе непрямую недоступны некоторые инструменты процессора, которые в могут в значительной мере оптимизировать в том числе и параллелизм.
Собственно поэтому и Ruby так же пошли по этому пути в новой версии.
Вопрос не в качестве реализации, а в том что будет, когда из такого «переключаемого языком потока» вызов пойдет наружу, в функции операционной системы и сторонних библиотек. Если потоки зеленые (переключаемые самим языком) — то пока такой вызов не отработает, остальные потоки будут стоять и ничего не делать. В этом проблема, а не в том какой там слайс и как хорошо они переключаются :).
Нет, я хочу сказать что это архитектурные отличия green threads от native threads. Велосипед не едет в гору, если не срктить педали, не потому что он криво реализован — а из-за арихтектурных отличий от мотоцикла.
Всё же кто сильнее — Сабзиро или Скорпион?
А МНЕ ПХП НРАВИТСЯ! ТОЛЬКО ПХП! ТОЛЬКО ХАРДКОР!
раби-раби-раби-раби!
Мой змий проглотит твой раби.
рАби ?! руби! Да с какого ***, простите раби? Го то гоогле транслате
… флейм? Добро пожаловать в комменты.
А еще вам пора на курсы по повышению троллеустойчивости.
Проверочное слово — study.
Да что вы говорите. Раби = Rubby. Руби = Ruby.
Вот вам ссылочка для ознакомления с транскрипцией.
Вот вам ссылочка для ознакомления с транскрипцией.
Проверочное слово:
— или рубин, если мы русифицируем название
— или google -> define:ruby, которое читается, как, сюрприз, /ruːbi/ (руби)
ЗЫ. Прежде, чем посылать людей на «проверочные» слова, советую ознакомится с этой ссылкой, если у вас существует уверенность, что в английском слова, которые пишутся похоже, читаются похоже
— или рубин, если мы русифицируем название
— или google -> define:ruby, которое читается, как, сюрприз, /ruːbi/ (руби)
ЗЫ. Прежде, чем посылать людей на «проверочные» слова, советую ознакомится с этой ссылкой, если у вас существует уверенность, что в английском слова, которые пишутся похоже, читаются похоже
Ну неужели вы думаете, что я не знаю, как на самом деле читается слово ruby?
В холиварном топике очень уместно злить рубистов проверенными годами методами, вы не находите?
В холиварном топике очень уместно злить рубистов проверенными годами методами, вы не находите?
> Ну неужели вы думаете, что я не знаю, как на самом деле читается слово ruby?
Я на Хабре уже и не знаю, что думать :)
Я на Хабре уже и не знаю, что думать :)
Здравствуйте. А можно глупый вопрос, при чём тут английский язык в принципе? Руби вроде японцем изобретён, а то, что название интерпретатора латинскими буквами записывается, вроде ни к чему никого не обязывает.
Название-то на английском.
Из чего это следует? Название это просто сочетание латинских букв. Латинские буквы следует читать по правилам русского прочтения латиницы, то есть «u» как «у».
en.wikipedia.org/wiki/Ruby_(programming_language)#Choice_of_the_name_.22Ruby.22
Не говоря уже о том, что и в английском оно читается с «у», у чем я и писал выше
Не говоря уже о том, что и в английском оно читается с «у», у чем я и писал выше
я целый семестр проучился на ин язе, чувак. я латынь знаю, ативус акузативус дуплек втфуплекс и прочее.
А уж чтение таких связочек в инглише и подавно. просто го то транслате
А уж чтение таких связочек в инглише и подавно. просто го то транслате
ТВОЙ ПЭХЕПЭ АЦТОЙ! ТОЛЬКО ЖДЖАВЫ!
Flawless Victory!


У меня еще больше заболела голова…
в OSX начиная с 10.6 он не работает для поставляемого с системой Ruby и нужно его перекомпилировать, что в целом не очень просто
rvm install 1.9.3
У Ruby сейчас активно идет переход с несовместимых веток 1.8 на 1.9 — довольно болезненный, мучительный и порождающий косяки.
Ничего подобного. Боль вызывает переход с rails 2.3.* на 3.*, и то по причине изменившегося API, а не изменений в corelib Ruby.
Как уже говорилось, разработка веб проектов не является для меня профильной, поэтому я рассматриваю больше со стороны автоматизации, server side, утилит. От рельсов далек. А вот переход с 1.8 на 1.9 лично меня задел довольно сильно — начиная от cassandra и заканчивая SOAP.
Почему-то тишина про то, какую боль вызывает переход на 3-ю версию питона.
Неплохая статья описывающая некоторые плюсы и минусы языков. Только ребят, не надо устраивать холивар на эту тему, в каждом языке есть свои плюсы и минусы, автор четко описал различия.
А его, кажется, не будет. По моему, все устали от них уже.
Мне нравятся оба, но ни одним из них я не пользуюсь :)
Автор лажанулся на самом главном — ограничиваться корелиб неудачная идея.
Если я не буду ограничиваться corelib — то статья лопнет, как та корова. Да и не думаю, что у меня хватит компетенции сравнить основные библиотеки по актуальным направлениям. Слишком большой объем работ, слишком много направлений. Для веба есть хорошие сравнения, ИМХО этого в первом приближении достаточно.
А ограничиваясь corelib вы не достигаете главного — корректного сравнения и определения удачных ниш.
Поэтому статью можно сократить до вывода собственно, так как все остальные пункты весьма и весьма сомнительны, и никакого отношения к делу не имеют. Впрочем выводы тоже сомнительны, потому что web на питоне программируют очень и очень активно, не меньше чем на рельсах.
Поэтому статью можно сократить до вывода собственно, так как все остальные пункты весьма и весьма сомнительны, и никакого отношения к делу не имеют. Впрочем выводы тоже сомнительны, потому что web на питоне программируют очень и очень активно, не меньше чем на рельсах.
Ах, а про веб в выводах ничего и нет, промахнулся.
Статья написана потому, что я не видел в интернетах сравнения именно про фичи языка. Сравнения фреймворков и библиотек — есть, легко гуглится. А сравнения о том, с чем сталкивается разработчик на практике — нету.
И потому, у меня редкий опыт — я в течении нескольких лет довольно активно пишу и на питоне, и на руби. Исследовательский отдел и все такое. Могу рассказать о косяках из первых рук :).
И потому, у меня редкий опыт — я в течении нескольких лет довольно активно пишу и на питоне, и на руби. Исследовательский отдел и все такое. Могу рассказать о косяках из первых рук :).
Было бы интересно еще почитать такое же сравнение с Node.js (Node.coffee)
Одни минусы бы были, стандартная библиотека же скудная :)
Что лучше модем или интернет? А как вы предлагаете сравнивать язык с приложением? 0_о
Оба хорошы. Но я их не использую.
Странно, мне всегда казалось, что у руби должно быть меньше строк кода чем в python, а в этой инфографике это не так. Надо пойти первоисточник попинать.
Лично меня удивило то, что предложений о работе для знающих питон нет даже в первой десятке. Наверное, Ruby более популярен в вебе из-за Ruby on Rails, а они смотрели в основном вакансии, связанные с вебом…
В инфографике присутствует functional php.
Скажите кто-нибудь — что это?
Скажите кто-нибудь — что это?
Видимо, вы имеете в виду место, где сравнивается быстродействие при использовании ОО и функционального подхода. Я не знаю, что авторы инфографики подразумевают под функциональным подходом, но на PHP >= 5.3 можно относительно удобно писать в функциональном стиле. Если интересно, можно начать читать отсюда.
Вот спасибо, давно думал попробовать руби раз на нем столько именитого крутится… теперь видно что смысла 0. но фреймворк вокруг него видимо накручен удобный, раз он еще не умер
но все равно, лучше всех — lua! :)
но все равно, лучше всех — lua! :)
Странные выводы. Если заниматься, например, сайтостроением, то Ruby (on Rails) — конфетка. Для десктопа не пробовал, не скажу.
Для десктопа… Кому-то нравится, кому-то нет… Те же Standalone приложения пишутся легко. Куча гуев на выбор. В стандартную поставку, например, Tk входит. Я писал уже как-то о создании приложения с использованием Тк. Можете в профиле посмотреть.
Для сайтостроения и Django — конфетка :) Так что тут, как уже говорилось, вопрос слишком холиварный :)
десктоп не нужен
На руби не найти ни одной нормальной библиотеки для научной работы, чтобы делать какие-то вычисления и выводить графики, а в Python есть SciPy.
Напиши)
SciRuby есть. Альфа, но все же.
Я вот никогда не понимал желания использовать Python или Ruby для научных расчётов. Есть же Mapple, Matlab и другие специализированные инструменты для этих целей.
В конце концов язык программирования — это лишь средство… и знание Python/Ruby — вовсе не повод пытаться заниматься научными расчётами с их помощью
В конце концов язык программирования — это лишь средство… и знание Python/Ruby — вовсе не повод пытаться заниматься научными расчётами с их помощью
Maple и Matlab, вообще говоря, другого типа инструменты. Например я видел программы написанные на Python для таких серьёзных расчётов как квантовая химия, однако их нельзя написать на Maple и Matlab. То есть возможно и получится написать, но работать это будет медленно и только на небольших примерах. Я уж не говорю о том, что они стоят денег и очень даже приличных.
Подтверждаю. Коллега с нейросетями долго специализированным инструментом мучился — тот матрицы от миллиона элементров грузил по десять минут и «специализированный» язык был очень сильно урезан — даже корректно распарсить входные файлы не получалось. Перешел на pybrain — все работает мгновенно и бесплатная интеграция со всем что движется, начиная от произвольного формата входных данных и заканчивая построением графиков и таблиц в пару строк кода.
Если вас не пугают доллары, собаки и проценты в именах переменных — пишите на перле :-)
Наверняка, на CPAN уже лежит модуль для нужных вычислений.
Наверняка, на CPAN уже лежит модуль для нужных вычислений.
Про кодировку файлов в питоне: docs.python.org/library/stdtypes.html#file.encoding
Переход на 3.x не выглядит столь уж отдалённой перспективой. Примерно половина, если не больше, распространённых библиотек сейчас уже поддерживают 3.x.
Переход на 3.x не выглядит столь уж отдалённой перспективой. Примерно половина, если не больше, распространённых библиотек сейчас уже поддерживают 3.x.
Мне одному кажется, что большинство описанных автором преимуществ и недостатков не являются преимуществами и недостатками?
Ну а как тогда сравнивать? Как сейчас модно — «В питоне декораторы и list comprehensions, в Ruby — блоки и DSL»? Это неинформативно. Я постарался собрать те вещи, которые лично мне при каждодневном использовании показались удобными / неудобными. А так как в общей сложности я занимаюсь разработкой уже более пятнадцати лет, то взгляд хотя и субъективный — но профессиональный :).
На мой взгляд принципиальных отличий между руби и питоном нет. Языки примерно одного плана, каждый со своими преимуществами и недостатками. И эти преимущества и недостатки, как мне кажется, не могут быть определяющими при выборе того, или иного языка.
Языки не важны, важны задачи, точнее говоря важен контекст в котором приходится эти задачи решать. Если нужно сделать десктопное приложение, то более выгоден питон, например за счет наличия указанных выше биндингов с Qt. Если веб-приложение, то возможно руби т.к. там есть рельсы, которые гораздо удобнее всего, что есть в мире питона (мое оценочное мнение:)). В контексте других задач будут, наверное, другие определяющие факторы.
Языки не важны, важны задачи, точнее говоря важен контекст в котором приходится эти задачи решать. Если нужно сделать десктопное приложение, то более выгоден питон, например за счет наличия указанных выше биндингов с Qt. Если веб-приложение, то возможно руби т.к. там есть рельсы, которые гораздо удобнее всего, что есть в мире питона (мое оценочное мнение:)). В контексте других задач будут, наверное, другие определяющие факторы.
>Возможность включать модули по относительному пути. Python технически это может, но большим
>количеством кода и с рядом неприятных спецэффектов.
>Лучшая поддержка работы со временем и датой. Стандартная библиотека Python даже с UTC не
>позволяет работать.
Стандратные либы (time и datetime) позволяют работать с UTC, и мне кажутся очень удобными. В чем по вашему заключется неудобство?
>количеством кода и с рядом неприятных спецэффектов.
from ..models import Page
>Лучшая поддержка работы со временем и датой. Стандартная библиотека Python даже с UTC не
>позволяет работать.
Стандратные либы (time и datetime) позволяют работать с UTC, и мне кажутся очень удобными. В чем по вашему заключется неудобство?
Неудобство заключается в том, что автор не шарит)
Ну вот, считаем что время на написание статьи себя окупило — я не знал про «from __future__ import absolute_import». Но тут надо посмотреть не убьет ли это чужие модули при активном использовании.
По поводу стандартной библиотеки и UTC. В Ruby я могу создать объект типа «время» вида «13:00 +4 UTC». И этот объект будет корректно работать с любыми другими объектами типа «время». В Python два типа объектов — «время с timezone» и «время без timezone» — их нельзя сравнивать. Более подробно все проблемы описаны вот тут: asvetlov.blogspot.com/2011/02/date-and-time.html
По поводу стандартной библиотеки и UTC. В Ruby я могу создать объект типа «время» вида «13:00 +4 UTC». И этот объект будет корректно работать с любыми другими объектами типа «время». В Python два типа объектов — «время с timezone» и «время без timezone» — их нельзя сравнивать. Более подробно все проблемы описаны вот тут: asvetlov.blogspot.com/2011/02/date-and-time.html
> Но тут надо посмотреть не убьет ли это чужие модули при активном использовании.
Это не убъет чужие модули, потому что «from __future__ import absolute_import» вы будете делать в своем модуле.
Это не убъет чужие модули, потому что «from __future__ import absolute_import» вы будете делать в своем модуле.
Да не надо это. Вы можете использовать относительные пути и без ``from __future__ import absolute_import``. А вот после этого импорта импортнуть файл в локальной директории без ``.`` уже не сможете, что иногда полезно.
Таймзоны, хм, ну там и написано все четко — те же темы, что и с юникодом.
Пункт два — а чего pytz не в стандартной библиотеке? А вы посмотрите когда очередная административная задница начинает выдумывать как чем-нибудь отметиться в истории, так все версии python обновлять что-ли сразу?
Таймзоны, хм, ну там и написано все четко — те же темы, что и с юникодом.
Пункт два — а чего pytz не в стандартной библиотеке? А вы посмотрите когда очередная административная задница начинает выдумывать как чем-нибудь отметиться в истории, так все версии python обновлять что-ли сразу?
А вы посмотрите когда очередная административная задница начинает выдумывать как чем-нибудь отметиться в истории, так все версии python обновлять что-ли сразу?
Это не ваша — програмистская забота, а наша — сисадминская.
Нам всё равно на всех серверах обновлять tzinfo в системе, в php, в java, итп.
И pytz в этом плане — гораздо проще.
На самом деле все что тут сказано — это дело привычки. Ничего такого особенного при выборе языка не увидел. И да — я питонист… :)
На самом деле обидно становится, когда и тот и другой изучишь — постоянно тянет в одном использовать лучшие фишки из другого и расстраивает, что их нет. Я сам на питоне больше пишу, но руби изучил из интереса. Теперь мне в питоне очень не хватает блоков, довольно часто с их помощью можно очень красиво и просто написать. А еще очень в руби нравится, что там нет такой чехарды с именованием как в питоне, очень раздражает, когда даже в базовой поставке языка в библиотеках CamelCase используется вместо официального underscore_case, ну и так далее в мелочах.
> На самом деле обидно становится, когда и тот и другой изучишь — постоянно тянет в одном использовать лучшие фишки из другого и расстраивает, что их нет.
Я пишу на питоне и пхп… представляете мой уровень расстройства когда пишу на пхп? :)
Я пишу на питоне и пхп… представляете мой уровень расстройства когда пишу на пхп? :)
Есть похожее.
У меня это выявляется когда пишу много Coffescript кода. Потом сложно переключиться на чистый яваскрипт и как-то противненько педалить на C# — всё кажется что этих скобочек слишком много.
У меня это выявляется когда пишу много Coffescript кода. Потом сложно переключиться на чистый яваскрипт и как-то противненько педалить на C# — всё кажется что этих скобочек слишком много.
> Примеры утрированы и сравнивают одинаковые возможности языков, без учета лучших практик их применения.
Ну так важны же практики применения. На руби надо писать как на руби, на питоне надо писать как пишут на питоне. Какой смысл вообще в таком сравнении?
Ну так важны же практики применения. На руби надо писать как на руби, на питоне надо писать как пишут на питоне. Какой смысл вообще в таком сравнении?
Хотя, вброс, наверное годны:)
Смысл в том, что любой язык программирования заточен под какие-то специфические задачи, которые на нем решаются лучше. На мой взгляд, знание сильных и слабых сторон позволяет лучше выбрать язык под задачу. Сложный shell скрипт лучше писать на Ruby. Сложное GUI приложение — на Python. На то есть причины — и я постарался их частично отразить.
Да, я понял. Выше уже отписался, но еще раз повторюсь — мне кажется, что ни руби ни питон не заточены под какие-то специфичные задачи, нет чего-то, что лучше решается на руби, и чего-то, что лучше решается на питоне. Я бы под задачу выбирал не язык, а фреймворк.
На правах вброса: в общем, я уже понял, что Tcl лучше и того, и другого, и причём уже давно :)
>Интерполяция строк позволяет включать в строки код на Ruby, автоматически подставляя в строку результат его выполнения.
Не очень понял что автор хотел здесь показать. Например, в питоне можно писать:
«test: %(result)d» % {'result': 1+23}
>Возможность создания временных папок с автоматическим удалением. В Python такая возможность появилась только в версии 3.2 — а это совсем отдаленное будущее.
tempfile вроде вполне себе в двойке есть.
>Есть языковая конструкция switch. А в python — нету.
Всегда казалось, что elif отлично покрывает юзкейс switch.
>В Python файл по умолчанию открывается в «текстовом режиме»
Странно видеть в списке «недостатков» логичное поведение по умолчанию какой-то функции. Если программист откроет бинарный файл без 'b', то он что называется сам виноват.
А вообще такой вопрос, имеет ли смысл для общего развития питонисту изучить Руби или лучше посомтреть на какой-то другой язык?
Не очень понял что автор хотел здесь показать. Например, в питоне можно писать:
«test: %(result)d» % {'result': 1+23}
>Возможность создания временных папок с автоматическим удалением. В Python такая возможность появилась только в версии 3.2 — а это совсем отдаленное будущее.
tempfile вроде вполне себе в двойке есть.
>Есть языковая конструкция switch. А в python — нету.
Всегда казалось, что elif отлично покрывает юзкейс switch.
>В Python файл по умолчанию открывается в «текстовом режиме»
Странно видеть в списке «недостатков» логичное поведение по умолчанию какой-то функции. Если программист откроет бинарный файл без 'b', то он что называется сам виноват.
А вообще такой вопрос, имеет ли смысл для общего развития питонисту изучить Руби или лучше посомтреть на какой-то другой язык?
Не очень понял что автор хотел здесь показать
Там специально есть картинка с разницей синтаксиса. На Ruby это делается внутри строки, на Python — вызовом для строки метода format.
tempfile вроде вполне себе в двойке есть.
tempfile есть, но для ряда задач — например, когда мы делаем в скрипте svn checkout или запускаем сборку, нам нужен не временный файл, а именно временная папка.
Если программист откроет бинарный файл без 'b', то он что называется сам виноват.
Это специфичное для Windows поведение. Для всех остальных операционных систем нет такого понятия как «текстовый файл». Учитывая, что Python и Ruby оба позиционируются как кроссплатформенные языки, я ожидаю более-менее одинакового поведения моего кода. И в Ruby файл всегда открывается как «бинарный», без спецэффектов.
А вообще такой вопрос, имеет ли смысл для общего развития питонисту изучить Руби или лучше посомтреть на какой-то другой язык?
Для общего развития, на мой взгляд, полезно. Вообщем, чем больше языков — тем лучше :).
>Там специально есть картинка с разницей синтаксиса. На Ruby это делается внутри строки, на Python — вызовом для строки метода format.
Т.е. в руби вы в строку впихиваете ещё и исполняемый код? Как-то мне это смешение не очень нравится.
>tempfile есть, но для ряда задач — например, когда мы делаем в скрипте svn checkout или запускаем сборку, нам нужен не временный файл, а именно временная папка.
tempfile — Generate temporary files and directories
>Это специфичное для Windows поведение
Хм, не замечал, т.к. работаю только под линуксом. Хотя в любом случае «специфичность» выглядит странно. Вы именно что проверяли в Линукс и в Виндовс данное поведение и наблюдали разницу?
Т.е. в руби вы в строку впихиваете ещё и исполняемый код? Как-то мне это смешение не очень нравится.
>tempfile есть, но для ряда задач — например, когда мы делаем в скрипте svn checkout или запускаем сборку, нам нужен не временный файл, а именно временная папка.
tempfile — Generate temporary files and directories
>Это специфичное для Windows поведение
Хм, не замечал, т.к. работаю только под линуксом. Хотя в любом случае «специфичность» выглядит странно. Вы именно что проверяли в Линукс и в Виндовс данное поведение и наблюдали разницу?
tempfile — Generate temporary files and directories
Python возвращает имя какой-то временной папки. Например, $TEMP. И ничего не удаляет. Ruby — создает временную папку и удаляет ее после выполнения скрипта.
Конечно. Это все описано в документации.
Python возвращает имя какой-то временной папки. Например, $TEMP. И ничего не удаляет. Ruby — создает временную папку и удаляет ее после выполнения скрипта.
Хотя в любом случае «специфичность» выглядит странно. Вы именно что проверяли в Линукс и в Виндовс данное поведение и наблюдали разницу?
Конечно. Это все описано в документации.
> Т.е. в руби вы в строку впихиваете ещё и исполняемый код? Как-то мне это смешение не очень нравится.
Есть два вида синтаксиса.
Можно вставлять выражения напрямую в строки: «some text #{some_ruby_expression}»
Можно использовать аналог format: «some text %s» % string_expression или «some text %s %f» % [string_expression, float_expression]
На практике если надо вставить всего одну переменную или какое-то простое выражение, то часто используют первый вариант, в более же сложных ситуациях — второй.
Есть два вида синтаксиса.
Можно вставлять выражения напрямую в строки: «some text #{some_ruby_expression}»
Можно использовать аналог format: «some text %s» % string_expression или «some text %s %f» % [string_expression, float_expression]
На практике если надо вставить всего одну переменную или какое-то простое выражение, то часто используют первый вариант, в более же сложных ситуациях — второй.
>на Python — вызовом для строки метода format.
И кстати, заметьте, что в примере который я привёл обошлось без явного вызова метода format.
И кстати, заметьте, что в примере который я привёл обошлось без явного вызова метода format.
(холивар?)
Для общего развития стóит изучить перл. В конце концов, перл повлиял и на руби, и на питон и на пхп.
Для общего развития стóит изучить перл. В конце концов, перл повлиял и на руби, и на питон и на пхп.
Ну и scheme ещё. Потому что есть SICP.
Про переход ruby на 1.9. Он всё-таки можно сказать уже завершен.
Старые проекты могут ещё крутиться на 1.8.7, но все новые гемы пишут под работу с 1.9, некоторые даже начинают дропать совместимость с 1.8, те же рельсы 4е, да и другие гемы тоже, плюс ree выпуск новых релизов сворачивают в пользу mri 1.9.
Соответственно всё, что вы записываете в минус из-за поддержки только в 1.9 для начинающих новые проекты таковым уже не будет.
Плюс если вы уж сравниваете переходы на новые версии, сравните заодно уже близкую миграцию python на 3.0 Тут всё на порядок или два печальнее.
Старые проекты могут ещё крутиться на 1.8.7, но все новые гемы пишут под работу с 1.9, некоторые даже начинают дропать совместимость с 1.8, те же рельсы 4е, да и другие гемы тоже, плюс ree выпуск новых релизов сворачивают в пользу mri 1.9.
Соответственно всё, что вы записываете в минус из-за поддержки только в 1.9 для начинающих новые проекты таковым уже не будет.
Плюс если вы уж сравниваете переходы на новые версии, сравните заодно уже близкую миграцию python на 3.0 Тут всё на порядок или два печальнее.
Тут скорее проблема в том, что в большинстве официальных линуксовых репозиториях, до сих пор лежит Ruby 1.8. Хотя конечно, для тех кто в теме, RVM решает все проблемы, но поверьте есть и те, кто не в теме.
В ряде случаев наши программы используются на компьютерах конечных пользователей. В случае Python там с высоко степенью вероятности будет версии 2.6 или 2.7. А вот в случае ruby там практически с равной веростностью будет 1.8 или 1.9. Так что процесс, конечно, близится к завершению, но пока не завершен :). BTW, я ничего особенного в недостатки из-за версии не записал. Наоборот, всячески подчеркнул, что в случае Ruby нужно использовать 1.9
BTW, сильное влияние оказывает версия интепретатора, идущая в комплекте с OS. Для OSX это до сих пор Ruby 1.8.x, RVM пользуются не все.
BTW, сильное влияние оказывает версия интепретатора, идущая в комплекте с OS. Для OSX это до сих пор Ruby 1.8.x, RVM пользуются не все.
Холиварная статья, конечно.
По поводу бонусов руби могу сказать что форматирование в питоне можно использовать следующим образом:
И что останов потока в любой момент — почти гарантированный способ выстрелить себе в ногу, если используется общая память.
По поводу бонусов руби могу сказать что форматирование в питоне можно использовать следующим образом:
print ('Name: %(name)s' % locals())
И что останов потока в любой момент — почти гарантированный способ выстрелить себе в ногу, если используется общая память.
Пример с разницей в синтаксисе для фрматирования — картинка под соответствующим пунктом сравнения.
Про выстрел в ногу и общую память — можно поподробнее?
Про выстрел в ногу и общую память — можно поподробнее?
Да, я видел картинки. Просто мне кажется что предложенный мною вариант лучше того, что указан там, и более близок к ruby-аналогу (лучше, если мы вообще считаем прямую подстановку переменных хорошей идеей, в чем я не уверен).
Общая память. Если поток, который мы собираемся убить, работает с объектом (для простоты), которым пользуются в других потоках, то он в частности может быть остановлен в середине любого метода этого объекта, потенциально оставляя его и любые его данные в inconsistent state. Это может приводить к феерическим багам и весьма неожиданному поведению. Не знаю как именно реализованы list и dict в python, но в яве, например, можно оставить в inconsistent state какой-нибудь совершенно базовый ArrayList, что приведет к абсолютной невозможности работать с ним далее.
Общая память. Если поток, который мы собираемся убить, работает с объектом (для простоты), которым пользуются в других потоках, то он в частности может быть остановлен в середине любого метода этого объекта, потенциально оставляя его и любые его данные в inconsistent state. Это может приводить к феерическим багам и весьма неожиданному поведению. Не знаю как именно реализованы list и dict в python, но в яве, например, можно оставить в inconsistent state какой-нибудь совершенно базовый ArrayList, что приведет к абсолютной невозможности работать с ним далее.
% — синтаксис в документации Python помечен как deprecated, рекомендуется использовать format.
И python, и ruby используют GIL, что нивелирует проблему для встроенных типов. Там есть нюансы, но они в плоскости race conditions, а не прямого нарушения потоками целостности общих данных.
Не знаю как именно реализованы list и dict в python, но в яве, например, можно оставить в inconsistent state какой-нибудь совершенно базовый ArrayList, что приведет к абсолютной невозможности работать с ним далее.
И python, и ruby используют GIL, что нивелирует проблему для встроенных типов. Там есть нюансы, но они в плоскости race conditions, а не прямого нарушения потоками целостности общих данных.
Не знал про %. Очень жаль, что они убирают такие удобные конструкции из языка, основным плюсом которого является удобство (да, изменение синтаксиса print мне тоже очень не нравится).
В любом случае, проблема с состоянием пользовательских данных остается.
В любом случае, проблема с состоянием пользовательских данных остается.
Подразумевается, что тот единственный поток, который работает с состоянием пользовательских данных, я убью по флагу. Но делать флаги для остальных потоков, которые куда-то коннектятся tcp, читают файла, ждут пайпов… Вообщем наличие языковой конструкции для их остановки помогает.
По поводу % — никто его не уберет, там теперь пишут «the % operator is supplemented by a more powerful string formatting method, format()» — в версии 3.0 думали, что в 3.1 объявят устаревшим, но вроде передумали.
По поводу print. Минусы понятны — в простом случае писать на 2 скобки больше. Но в консоли с ipython его можно по-старому вызывать (т.к. ipython поддерживает вызов функций без скобок). Ну и в print теперь можно аргументы передавать и разыменовывать их print(*args), или саму print как коллбэк передавать куда-то в аргументы, так что и плюсы есть)
По поводу print. Минусы понятны — в простом случае писать на 2 скобки больше. Но в консоли с ipython его можно по-старому вызывать (т.к. ipython поддерживает вызов функций без скобок). Ну и в print теперь можно аргументы передавать и разыменовывать их print(*args), или саму print как коллбэк передавать куда-то в аргументы, так что и плюсы есть)
> Очень жаль, что они убирают такие удобные конструкции из языка,
Я тоже думал что это конструкция языка. Но на самом деле это просто реализация basestring, в которой есть магический метод __mod__().
Я тоже думал что это конструкция языка. Но на самом деле это просто реализация basestring, в которой есть магический метод __mod__().
На лукоморье реализацию очень круто описали.
lurkmore.to/Выстрелить_себе_в_ногу
lurkmore.to/Выстрелить_себе_в_ногу
Вы упустили самое главное — как со скоростью?
А я не любитель предварительной оптимизации, мне все равно как у них со скоростью. Будет что тормозит — я могу тормозяющую часть оформить как расширение на C и будет мне счастье.
Не все знают с, а некоторые так знают с, что скорость может быть меньше (утечки, ошибки итд). Поэтому и интересна скорость самих языков.
Это и без меня десятки раз сравнивали :)
Вы еще там пункт забыли что у питона аргументы в функции/методе создаются на стадии интерпретации а не на стадии вызова, и это может повлечь за собой ошибки у невнимательных =)
Я не знаю для питонцев это преимущество или недостаток, но для остальных это явно неожиданное поведение.
def q(a=[]):
a.append(1)
print(a)
q(); // [1]
q(); // [1, 1]
Я не знаю для питонцев это преимущество или недостаток, но для остальных это явно неожиданное поведение.
любопытно! неожиданное, согласен
Тут момент вообще тонкий для начинающих, надо понимать разницу между mutable и immutable
def q(a=""): a += "a" print(a) q(); // "a" q(); // "a"
В любых языках есть ссылочные типы, другое дело в порядке инициализации аргументов в функции, в других языках они инициализируются каждый раз при вызове функции, в отличии от питона
В том-то и дело, что в питоне всё передается по ссылке, поэтому меняется сам объект, в данном случае массив.
С помощью такой фишки можно пилить синглтоны без явного объявления синглтона
Руби в синглтонах побьет кого угодно =) тут смотрел примеры
Примеры кривые, вот краткий python:
class Singleton(object):
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__new__(cls)
return cls.instance
Так запилите его в википедию.
Запилил.
И мир стал на несколько строчек лучше!
Между прочим, предыдущий вариант на метаклассе был лучше: в данной реализации __init__ будет вызываться при каждом инстанцировании класса, вне зависимости от того новый экземпляр возвращается или ранее созданный! Т.о. придётся инициализацию переносить в метод типа __init2__ и вызывать вручную в __new__ при создании нового объекта, а __init__ оставлять пустым. Ну и потомки этого класса не будут иметь возможности иметь аргументы инициализации.
Да, правы, __init__ вызывается, косяк.
Аргументы. Давайте рассудим — вот я вызываю a = Singleton(234), а в другом месте вызову b = Singleton(8903890). Вот тут я как-то в замешательстве, а что с этим делать? То есть как бы я уже создал один синглетон, который 234, а что делать с новым, у которого 8903890?
Аргументы. Давайте рассудим — вот я вызываю a = Singleton(234), а в другом месте вызову b = Singleton(8903890). Вот тут я как-то в замешательстве, а что с этим делать? То есть как бы я уже создал один синглетон, который 234, а что делать с новым, у которого 8903890?
Тем не менее аргументы могут понадобиться, как параметры создания первого экземпляра, поэтому всё же лучше предоставить возможность, а не наложить ограничение (ИМХО).
А повторный вызов с другими аргументами можно перенаправить в явный метод типа _update(...). Скажем у нас есть сквозной singleton-журнал, и повторное «инстанцирование» со строкой-параметром дополняет уже существующий журнал.
Опять же через параметры конструктора можно реализовать не singleton, но cache, ключами которого будут хэши параметров
А повторный вызов с другими аргументами можно перенаправить в явный метод типа _update(...). Скажем у нас есть сквозной singleton-журнал, и повторное «инстанцирование» со строкой-параметром дополняет уже существующий журнал.
Опять же через параметры конструктора можно реализовать не singleton, но cache, ключами которого будут хэши параметров
Ну предыдущий вариант явно разрешает принять аргументы, потом пихает их в первый вызов __init__, а последующие тупо игнорит.
Сказать `хрен вам` и то в сто раз прекраснее чем подложить такую свинью :)
В общем надо подумать и запилить абсолютно правильную реализацию синглтона на все случаи жизни, пусть и, эх эх, не столь краткую.
Сказать `хрен вам` и то в сто раз прекраснее чем подложить такую свинью :)
В общем надо подумать и запилить абсолютно правильную реализацию синглтона на все случаи жизни, пусть и, эх эх, не столь краткую.
Видел код, где с помощью этого поведения сделано кэширование «навсегда» =)
Ой, это же скользкая тема :) Во первых сам cpython быстрее, но не критично. А во вторых, если не выходим за рамки stdlib, легким движением запускаем через pypy и взлетаем в космос. Сейчас прогнал свой древний raytracing пример на pypy, скорость меня приятно удивила.
По примеру с регулярным выражением, если сильно хочется — на python можно записать ничуть не хуже:
x, y = re.search(r'(\d+)x(\d+)', '30x20').groups()
Не-named capture groups приводят к проблемам, если возможно частичное совпадение (например, в regexp есть «или»). Также в вашем случае будет exception, если совпадения нет (search вернет None) :).
Тогда можно использовать элегантный и нечитаемый говнокод:
x, y = (lambda x, y: (x, y))(**getattr(re.search(r'(?P\d+)x(?P\d+)', '30x20'), 'groupdict', lambda: [None] * 2)())
что-то меня понесло)
Трюки и фокусы я тоже знаю. Интерполяция в словарь locals() и прочее. Но такой куд труднее читать и поддерживать. Я рассматриваю базовый синтаксис языка, который можно встретить в реальных приложениях и который в целом используется большинством программистов. Эзотерические техники существуют, но они за рамками этой статьи. Может быть напишу следующую про эмуляцию рубиновой интерполяции в питоне — есть ряд интересных наработок. Но это скорее курьез для развлечения, нежели техника, которую стоит применять в production коде.
Или так:
x, y = (
lambda s: s.groups() if s else (None, None)
)(
re.search(r'(\d+)x(\d+)', '30x20')
)
Описанными языками не владею, но прочитал сравнение с удовольствием.
Судя по эмоциям, вы хаскелевец или лисповец.
К сожалению PHPшник. Почему к сожалению? Не потому что PHP плохой язык, а потому что знаю только его на хорошем уровне. Тем не менее, усиленно пытаюсь заставить себя изучить python.
А в пхп что-нибудь из сравниваемого вообще есть?
Я бы отметил тот факт, что полно документации, соответственно, низкий порог вхождения. Встроенная поддержка огромного количества движков БД. Написано много библиотек (не могу сравнить с питоном и тем более руби, но полагаю, что много больше).
Из минусов — не умеет так низкоуровнево работать с потоками вообще с железом. Хотя, ему это и не сильно нужно — специфика другая.
PS/ Сравнить не могу, для этого нужно знать больше о других языках.
Из минусов — не умеет так низкоуровнево работать с потоками вообще с железом. Хотя, ему это и не сильно нужно — специфика другая.
PS/ Сравнить не могу, для этого нужно знать больше о других языках.
— встроенная поддержка JSON
— встроенная поддержка sqlite
— встроенная поддержка архивов
— в целом более распространен (в вебе уж точно)
— хорошая обратная совместимость между актуальными версиями (я бы сказал слишком хорошая)
— интерполяция строк
— встроенная поддержка SSL
— возможность включать «модули» по относительному пути (плюс автозагрузка)
— встроенный шаблонизатор, вернее PHP является шаблонизатором :)
— хорошая поддержка даты и времени (субъективно)
Итого из 32 плюсов из топика PHP обладает 12, причем как плюсами питона, так и руби. И, возможно, для кого-то именно такая комбинация плюсов перевесит минусы (коих субъективно больше чем в питон и руби вместе взятых)
— встроенная поддержка sqlite
— встроенная поддержка архивов
— в целом более распространен (в вебе уж точно)
— хорошая обратная совместимость между актуальными версиями (я бы сказал слишком хорошая)
— интерполяция строк
— встроенная поддержка SSL
— возможность включать «модули» по относительному пути (плюс автозагрузка)
— встроенный шаблонизатор, вернее PHP является шаблонизатором :)
— хорошая поддержка даты и времени (субъективно)
Итого из 32 плюсов из топика PHP обладает 12, причем как плюсами питона, так и руби. И, возможно, для кого-то именно такая комбинация плюсов перевесит минусы (коих субъективно больше чем в питон и руби вместе взятых)
Согласен, но поддержка UTF-8 достаточно печальная и не всегда работает как надо.
JSON при этом не работает корректно с кириллицей (использование кириллицы — абсурд, но это все же недостаток).
Про движки БД я упомянул — считаю что это огромный плюс.
Про совместимость — это иногда проблема, так как тащит огромный легаси, но поддерживать проект на пыхе, конечно, удобнее в этом плане.
ССЛ — юзал не часто, но поддержка действительно есть.
Дата и время, считаю что слабая сторона пыха. DateTime, конечно, есть, но работа с ним не тривиальна.
Многие обозначенные Вами плюсы являются полуплюсами, ИМХО, но пых бросать пока не собираюсь — люблю его :)
JSON при этом не работает корректно с кириллицей (использование кириллицы — абсурд, но это все же недостаток).
Про движки БД я упомянул — считаю что это огромный плюс.
Про совместимость — это иногда проблема, так как тащит огромный легаси, но поддерживать проект на пыхе, конечно, удобнее в этом плане.
ССЛ — юзал не часто, но поддержка действительно есть.
Дата и время, считаю что слабая сторона пыха. DateTime, конечно, есть, но работа с ним не тривиальна.
Многие обозначенные Вами плюсы являются полуплюсами, ИМХО, но пых бросать пока не собираюсь — люблю его :)
Если кратко, то многое. Точно нет потоков и нормального юникода. остальное лень выискивать — спать охота.
Требуется PHPшник на постоянную работу. И это не шутка.
ruby лучше. rails самый лучший, самый удобный, самый защищенный фреймворк. rubyist это самый добрый и умный гик.
Подожди, не торопись. Пусть они поверят, что мы здоровы.
:-)
:-)
Да и джанго как бы не покушать зашел :) Я бы даже сказал, на российском рынке сейчас на джангистов спрос куда выше, чем на рельсовиков.
обоснуй? rubyjobs.ru
И что доказывает эта ссылка? На hh поиск по python — 673 вакансии за месяц, по ruby — 250. Как вариант.
Если возможно, сравните вакансии именно относительно фреймворков — Django и RoR. Тогда и поговорим.
Пожалуйста — по запросу django 91 вакансия, по запросу ruby on rails 79. Да и по личному опыту знаю, что в 90% случаев вакансии по питону именно на джангу, еще процентов пять — администраторы, им для автоматизации. Оставшиеся — редкие вакансии в крупных компаниях на специфические должности, где питон не для веба. Насчет руби говорить не буду, но подозреваю, что и там примерно те же пироги, если уклон в веб не больше.
Ну ты приколист)) еще бы на сайте rubyjobs.ru было меньше вакансий ruby)) а сайтов связанных с вакансиями питон тож полно если что включая специализированные для Django.
Сказал тот, кто недавно «ломанул» репозиторий rails на github.
передавать команду и ее аргументы не строкой, а списком.Насколько я знаю, причина, по которой аргументы передают не строкой а списком — повышение безопасности (исключение shell — инъекций).
И пробелы. Иначе не работает. Лично проверял :(.
Можете пример кода привести на Ruby и Python. Я просто не до конца понимаю что за проблема.
Примерно вот так (пишу по памяти, конкретные детали могут быть написаны с ошибками):
Ruby:
Python:
Ruby:
# Будет работать
`"c:/program files/some app/app.exe" "c:/documents and settings/some file.txt"`
Python:
# Не будет работать.
subprocess.check_output( '"c:/program files/some app/app.exe" "c:/documents and settings/some file.txt"' )
# Будет работать
subprocess.check_output( [ "c:/program files/some app/app.exe", "c:/documents and settings/some file.txt" ] )
shell=True попробуйте добавить
Видимо ruby по умолчанию вызывает команду через промежуточный shell (bash/sh) а питон запускает напрямую (ресурсы экономит??)
subprocess.check_output( '"c:/program files/some app/app.exe" "c:/documents and settings/some file.txt"' , shell=True)
Видимо ruby по умолчанию вызывает команду через промежуточный shell (bash/sh) а питон запускает напрямую (ресурсы экономит??)
Там все перепробовано. Не работает (с).
$ echo 'dance dance' > 'lets dance.txt'
$ "/bin/cat" "/home/seriy/lets dance.txt"
$ python
>>> import subprocess
>>> subprocess.check_output('"/bin/cat" "/home/seriy/lets dance.txt"')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 537, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1239, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
>>> subprocess.check_output('"/bin/cat" "/home/seriy/lets dance.txt"', shell=True)
'dance dance\n'
Возможно только на Windows проблема, проверить не на чем…Извините меня, но при установке для Windows, Tk для Ruby уже есть «из коробки».
эт скорее потому что вы ставили с rubyinstaller.org/ а не с www.ruby-lang.org ;)
я им сам пользуюсь, там МНОГО чего полезного прям в коробке
особенно радует наличие DevKit (ставим отдельно)
для сборки gem которым «С» нужен…
я им сам пользуюсь, там МНОГО чего полезного прям в коробке
особенно радует наличие DevKit (ставим отдельно)
для сборки gem которым «С» нужен…
Совершенно верно. Я просто автора не понял. Что он за инсталлятор использовал, что у него Тк «из коробки» нема.
Оно там есть, но галочка в инсталляторе по умолчанию снята. Так что у олшинства пользователей, поставивших ruby с помошью ruby installer, Tk не будет :). Это и практики развертывания скриптов в корпоративной сети.
Спасибо за сравнение, познавательно
сам пишу на руби, он в общем красив и понятен ;)
но многие на стороне используют питон, как встроенный/дефолтный, по этому Ваш обзор и интересен.
для меня еще аргумент в сторону ruby это синтаксис работы с регекспами — нативынй
сам пишу на руби, он в общем красив и понятен ;)
но многие на стороне используют питон, как встроенный/дефолтный, по этому Ваш обзор и интересен.
для меня еще аргумент в сторону ruby это синтаксис работы с регекспами — нативынй
print "Hello #{$1} world" if var =~ /regexp(.*)$/
Собственно, на чём говорить, на русском или на английском?
Буду говорить на английском — в моём городе большинство меня не поймёт, так как у нас национальный язык РУССКИЙ, так же и тут, для решения одной задачи удобноее «говорить на питоне», а для другой — на раби.
И в чём смысл статьи?
Буду говорить на английском — в моём городе большинство меня не поймёт, так как у нас национальный язык РУССКИЙ, так же и тут, для решения одной задачи удобноее «говорить на питоне», а для другой — на раби.
И в чём смысл статьи?
имхо — как раз и показать это
это два языка из одной группы, (руби начинался как более объектный питон с примесью перла ?)
это два языка из одной группы, (руби начинался как более объектный питон с примесью перла ?)
combines syntax inspired by Perl with Smalltalk-like features. It was also influenced by Eiffel and Lisp.
it is therefore similar in varying respects to Smalltalk, Python, Perl, Lisp, Dylan, Pike, and CLU.
Ну и blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/179642
So, Ruby was a Lisp originally, in theory.
руби
>>>Интерполяция строк позволяет включать в строки код на Ruby, автоматически подставляя в строку результат его выполнения.
>>>print( «Name: {name}».format( name = name ) )
Хотел было предложить print( «text_prefix»+`py_expr`+«text_suffix» ) с намёком на то, что "+` и `+" аналогичны #{ и }. Но понял, что это не совсем то же самое, хоть и похожее.
>>>print( «Name: {name}».format( name = name ) )
Хотел было предложить print( «text_prefix»+`py_expr`+«text_suffix» ) с намёком на то, что "+` и `+" аналогичны #{ и }. Но понял, что это не совсем то же самое, хоть и похожее.
А давайте дополним может сравнение? Я как бы по руби сам не много могу с уверенностью сказать, так как по верхушкам смотрел, для расширения кругозора.
Но в общем библиотеки это важно, глупо не пользоваться библиотеками. А потому нужны инструменты для работы с ними — rvm, virtualenv etc. Что лучше я вот не могу сказать, так как с rvm не возился.
Альтернативные реализации. То есть jruby, ironruby, ironpython, jython, pypy.
Биндинги, есть для ruby что-то вроде Cython? Есть проекты типа pypy?
Но в общем библиотеки это важно, глупо не пользоваться библиотеками. А потому нужны инструменты для работы с ними — rvm, virtualenv etc. Что лучше я вот не могу сказать, так как с rvm не возился.
Альтернативные реализации. То есть jruby, ironruby, ironpython, jython, pypy.
Биндинги, есть для ruby что-то вроде Cython? Есть проекты типа pypy?
На счет болезненности перехода с 1.8 на 1.9 — чушь. Как тут ранее верно заметили, это касается перехода с рельс 2.х на 3.x. Но не рельсами едиными живо ruby, как говорится…
На счет многозадачности… В ruby майнстримом признана другая парадигма. Почитайте про fibers. Это что-то типа реализации кооперативной многозадачности внутри руби и является абсолютно переносимым решением.
Автор совсем ничего не сказал про метапрограммирование, duck-typing, встроенный фреймворк тестирования minitest (это для ruby 1.9) и прочая. А это в ruby «наше всё»… Впрочем, признаюсь, как с этим обстоят дела на питоне я вообще не в курсе. Возможно не хуже…
Всё-таки изрядно видно, что автор больше питонист, мышление у него явно не ruby-style.
Мне например, присваивать переменной функцию даже в голову не приходило. Для этого в руби используются лямбда-функции. Как никак это уже относится к функциональному программированию.
То как это сделано на питоне выглядит для меня как грязный хак.
Но за общий доброжелательный тон обзора — респект. Была бы возможность, плюсанул бы обязательно…
На счет многозадачности… В ruby майнстримом признана другая парадигма. Почитайте про fibers. Это что-то типа реализации кооперативной многозадачности внутри руби и является абсолютно переносимым решением.
Автор совсем ничего не сказал про метапрограммирование, duck-typing, встроенный фреймворк тестирования minitest (это для ruby 1.9) и прочая. А это в ruby «наше всё»… Впрочем, признаюсь, как с этим обстоят дела на питоне я вообще не в курсе. Возможно не хуже…
Всё-таки изрядно видно, что автор больше питонист, мышление у него явно не ruby-style.
Мне например, присваивать переменной функцию даже в голову не приходило. Для этого в руби используются лямбда-функции. Как никак это уже относится к функциональному программированию.
То как это сделано на питоне выглядит для меня как грязный хак.
Но за общий доброжелательный тон обзора — респект. Была бы возможность, плюсанул бы обязательно…
Автор совсем ничего не сказал про метапрограммирование, duck-typing, встроенный фреймворк тестирования minitest (это для ruby 1.9) и прочая. А это в ruby «наше всё»… Впрочем, признаюсь, как с этим обстоят дела на питоне я вообще не в курсе. Возможно не хуже…
Примерно одинакого. Про DSL и декораторы я написал, остальное достаточно минорные различия, которые мало на что влияют в коде и не могут быть признаны слабыми и сильными сторонами :). Встроенный фреймворк тестирования в питоне такой же, но на практике все равно все используют внешние системы тестирования, интегрированные с continous integration
Всё-таки изрядно видно, что автор больше питонист, мышление у него явно не ruby-style.
Мне например, присваивать переменной функцию даже в голову не приходило. Для этого в руби используются лямбда-функции. Как никак это уже относится к функциональному программированию.
Спасибо на добром слове, но я их примерно в равной степени использую. Руби мне импонирует чуть больше — DSL, регэкспы, shell. Но отсутствие потоков и слабая документация убивают. «Присваивать переменной функцию» — это типичное делегирование. Например, активно применяется в Qt. Аналогичный код на Ruby с замыканиями и блоками будет больше по размеру.
Есть потрясающий(для меня точно) доклад от Yehuda Katz «Why ruby isn't python» с конференции RuPy
blip.tv/rupy-strongly-dynamic-conference/yehuda-katz-tradeoffs-and-choices-why-ruby-isn-t-python-5726460
где он рассказывает о некоторых принципах, лежащих в основе ruby, почему оно всё работает именно так как есть, сравнивая с аналогичными вещами в python, и почему некоторые концепции в других языках с точки зрения рубиста 'сломаны'
blip.tv/rupy-strongly-dynamic-conference/yehuda-katz-tradeoffs-and-choices-why-ruby-isn-t-python-5726460
где он рассказывает о некоторых принципах, лежащих в основе ruby, почему оно всё работает именно так как есть, сравнивая с аналогичными вещами в python, и почему некоторые концепции в других языках с точки зрения рубиста 'сломаны'
> То как это сделано на питоне выглядит для меня как грязный хак.
вы про x = func? где здесь грязь и где здесь хак?
вы про x = func? где здесь грязь и где здесь хак?
Если я правильно понимаю, функция своим именем занимает имя в пространстве имен переменных. То есть код:
выдаст ошибку. То есть программируя на python'е я должен следить, чтобы случайно не назвать переменную именем библиотечной функции, например.
Понятно. что питонисты это уже на автопилоте отслеживают, но назвать это хорошей идеей сложно.
Хотя бы потому, что случаи присваивания функции переменной это куда более редкая операция, чем просто присваивание числа переменной даже в python'е. Ради нечастой фичи приходится постоянно контролировать именование переменных.
def func( a, b) :
return a + b
func = 1
func( a=1, b=2 )
выдаст ошибку. То есть программируя на python'е я должен следить, чтобы случайно не назвать переменную именем библиотечной функции, например.
Понятно. что питонисты это уже на автопилоте отслеживают, но назвать это хорошей идеей сложно.
Хотя бы потому, что случаи присваивания функции переменной это куда более редкая операция, чем просто присваивание числа переменной даже в python'е. Ради нечастой фичи приходится постоянно контролировать именование переменных.
Это не аргумент против функций как объектов первого рода. Ровно также можно напороться на:
func = "s"
func + 2
Для отлова таких ошибок есть статические анализаторы, например pylint. Это общая проблема динамической типизации, она не ограничивается функциями.
> Впрочем, признаюсь, как с этим обстоят дела на питоне я вообще не в курсе.
А о чем вы тогда хотите нам рассказать?
> То как это сделано на питоне выглядит для меня как грязный хак.
А присваивание обычных переменных тоже грязный хак? В Питоне все объект, вообще все. И объявление функции — это такое же присваивание переменной объекта функции, который является callable. Кстати, не только объекты функции являются callable.
А о чем вы тогда хотите нам рассказать?
> То как это сделано на питоне выглядит для меня как грязный хак.
А присваивание обычных переменных тоже грязный хак? В Питоне все объект, вообще все. И объявление функции — это такое же присваивание переменной объекта функции, который является callable. Кстати, не только объекты функции являются callable.
Вам ни о чем. Вы в этом не нуждаетесь, как я понимаю. Я просто комментировал статью. То, что я назвал это довольно важный функционал в ruby, без этого ruby как язык был бы значительно слабее.
В ruby тоже всё объект.
Общее пространство имен для функций и для переменных создает на мой взгляд довольно серьезные ограничения. А выгода, получается, только в том, что при написании интерпретатора нет необходимости создавать отдельную таблицу для имен функций, всё можно сваливать в одну кучу.
Или я не прав? Какие возможности это дает python'у?
В ruby тоже всё объект.
Общее пространство имен для функций и для переменных создает на мой взгляд довольно серьезные ограничения. А выгода, получается, только в том, что при написании интерпретатора нет необходимости создавать отдельную таблицу для имен функций, всё можно сваливать в одну кучу.
Или я не прав? Какие возможности это дает python'у?
Таки в руби функция — объект первого класса или как?
Нет, к сожалению. Более того, вызов функции можно делать без круглых скобок — так что просто идентификатор функции это уже ее вызов О_О. У меня там в одном из примеров иллюстрация как функция оборачивается в proc через хитрую конструкцию с амперсандом и двоеточием, «symbol#to_proc».
Вот меня это и смутило.
Получается, что для функциональных приёмов программирования руби совсем никак не подходит?
Ни map/reduce, ни колбэков, ни функторов/декораторов?
Получается, что для функциональных приёмов программирования руби совсем никак не подходит?
Ни map/reduce, ни колбэков, ни функторов/декораторов?
ar = ['12', 'abc']
ar.map(&:size) # => [2, 3]
совсем нет, и map, и inject, и колбэки — всё есть
Вы будите смеяться, но при де факто отсутствующих декораторах и функциях, которые совсем не first class object — Ruby в рамках стандартной библиотеки предоставляет гораздо больше приемов функционального программирования, нежели питон. Выше уже написали ряд примеров. Хорошая стандартная библиотека, много алгоритмов, динамические сообщение (объекту можно послать size даже если у него нет такого метода, вернется nil) — видно, что этим пользуются, для людей сделано.
Тут ведь как — если функции первоклассные, то количество приёмов ограничено только фантазией программиста.
А что именно есть в стандартной библиотеке руби?
(я не смог адекватно сориентироваться в документации по нему)
Википедия же говорит, что основные особенности есть и там и там.
А что именно есть в стандартной библиотеке руби?
(я не смог адекватно сориентироваться в документации по нему)
Википедия же говорит, что основные особенности есть и там и там.
map, reduce, inject, fold, select, reject, each…
э… таки.
reduce, inject, fold — это же синонимы.
select и reject — почти одно и тоже с точностью до отрицания условия.
each и map — одно и тоже в силу «всё возвращает результат»
Я знаю, что одна из основных задумок рубирисовать анимированных верблюдиков ascii-артом разнообразить текст программы и создавать иллюзию большого выбора методов решения элементарных задач.
Но это же всего ТРИ фичи, причом самых элементарных. И никак не «гораздо больше».
А как, например, с функциональными замыканиями, каррингом, continuations?
reduce, inject, fold — это же синонимы.
select и reject — почти одно и тоже с точностью до отрицания условия.
each и map — одно и тоже в силу «всё возвращает результат»
Я знаю, что одна из основных задумок руби
Но это же всего ТРИ фичи, причом самых элементарных. И никак не «гораздо больше».
А как, например, с функциональными замыканиями, каррингом, continuations?
карринг есть.
continuations есть.
Функциональные замыкания — это что такое?
continuations есть.
Функциональные замыкания — это что такое?
var outervar = foo;
function func() {
var self = this;
var localvar = bar;
...
function myclosure(data) { self.dosomething(data, localvar, outervar); }
$.ajax({ url: "url.json", success: myclosure });
localvar = baz;
...
}
В качестве колбэка success передана не функция, но замыкание.
В нём замкнуты переменные self, localvar, outervar.
При её выполнении эти переменные будут связаны со значениями установленными в контексте, в котором определена функция.
В частности, localvar == baz, и outervar == foo (если за время выполнения запроса они не изменятся).
При её выполнении эти переменные будут связаны со значениями установленными в контексте, в котором определена функция.
Не понял. При выполнении myclosure после выхода из контекста функции func() — значения «localvar» и «outerval» должны быть какие? Какие они были на момент объявления myclosure, какие они были на момент выхода из контекста func() (там я вижу localvar меняется) или какие они есть на момент вызова?
Вот что я могу соорудить на скорую руку по вашему описанию:
Выведет:
Это то или не то?
$outervar = 1
$outerclosure = nil
def func()
localvar = 10
myclosure = ->( data ) { p data, localvar, $outervar; }
$outerclosure = myclosure
localvar = 20
end
func()
$outerclosure.call( "foo" )
Выведет:
"foo"
20
1
Это то или не то?
А как же Файберы в Ruby 1.9? Очень мощная штука. Например, с её помощью можно писать асинхронный код в синхронном стиле github.com/igrigorik/em-synchrony. Или в Rails 3.1 с её помощью реализовали отдачу верхушки layout до выполнения кода основного шаблона.
Файберы — это другое название для «green threads». Ну да, они есть. В питоне тоже генераторы есть — это примерно равноценные механизмы, никаких явных преимуществ тут нет. А то, что я в питоне могу в отдельном потоке пообщаться с операционной системой без остановки логики программы, а в руби не могу — тут уже разница.
Green threads (потоки на уровне языка) вроде совсем другое. Файберы даёт API по управлению точки выполнения программы. Поэтому можно реализовывать хитрые штуки, как в случае с асинхронным кодом. Есть пример у генераторов в Python, которые дают тоже самое?
Про асинхронность я имею в виду:
req1 = http.request('google.com')
# делается запрос, но программа продолжает выполняться, пока мы ожидаем ответа от ОС
req2 = http.request('yandex.ru')
# снова запрос уходит в фон
puts req1.title + req2.title
# как только нам понадобилось что-то из фоновых запросов, мы прекращаем выполнение программы и ждём ответа, следующие строки программы будут выполняться только когда загрузятся данные от обоих фоновых запросов
Генераторы это генераторы, они explicit. То что вы показываете это скорее greenlet или stackless python.
В общем сейчас дефакто используют greenlet. Так как в самом python есть генераторы. которые типа тоже корутины, то гринлетов в корелиб не будет никогда.
В общем сейчас дефакто используют greenlet. Так как в самом python есть генераторы. которые типа тоже корутины, то гринлетов в корелиб не будет никогда.
С ходу не смогу ответить, никогда таким типом синхронизации не интересовался.
Нда. Человек сделавший обзор Ruby vs Python не знает разницу между Fibers и Green thread.
Я не кормлю троллей по принципиальным соображениям :).
Спасибо за информацию. А теперь идите и почитайте, что-то о языках о которых вы говорили. Я руку от лица не убирал с первых строчек. Забавно, имено вот такие неучи мне и слили карму.
Я зарабатываю деньги разработкой программ уже более пятнадцати лет. И чуток разбираюсь в программировании вообще, и в этих языках в частности. А что до точности формулировок — я не книгу пишу, могу себе позволить выражать мысли как мне нравится. Вот буду писать статью о зеленых потоках, генераторах, файберах, приемах их использования и разнице в реализациях — будет точность формулировок и википедия.
Забавно, если я — неучь, то кто же тогда, кроме вас конечно, профессионал? Авторы языка? :)
Забавно, если я — неучь, то кто же тогда, кроме вас конечно, профессионал? Авторы языка? :)
> Я зарабатываю деньги разработкой программ уже более пятнадцати лет.
Начался ageism. Не прав? Старше собеседника? Напомни ему об этому!
> И чуток разбираюсь в программировании вообще, и в этих языках в частности.
В чем суть тогда обзора, если вы разбираетесь «чуток»?
> А что до точности формулировок — я не книгу пишу, могу себе позволить выражать мысли как мне нравится.
Вы вводите людей в заблуждение называя Fibers зелеными тредами.
> Забавно, если я — неучь, то кто же тогда, кроме вас конечно, профессионал? Авторы языка? :)
Вот например он — Ilya Grigorik. А вы или реально ничего не знаете о языках о которых вы написали (выглядит как сравнение 2х статей из википедии) или уебдевелопер. А то, что сравнение сильно притянуто в python выдает всю субъективность.
Начался ageism. Не прав? Старше собеседника? Напомни ему об этому!
> И чуток разбираюсь в программировании вообще, и в этих языках в частности.
В чем суть тогда обзора, если вы разбираетесь «чуток»?
> А что до точности формулировок — я не книгу пишу, могу себе позволить выражать мысли как мне нравится.
Вы вводите людей в заблуждение называя Fibers зелеными тредами.
> Забавно, если я — неучь, то кто же тогда, кроме вас конечно, профессионал? Авторы языка? :)
Вот например он — Ilya Grigorik. А вы или реально ничего не знаете о языках о которых вы написали (выглядит как сравнение 2х статей из википедии) или уебдевелопер. А то, что сравнение сильно притянуто в python выдает всю субъективность.
greenlets?
И ещё нет, что у Ruby есть символы — поиск в хеше по символу идёт гораздо быстрее. Хотя может в Python тоже есть что-то подобное.
Да, символы настолько самоочевидны, что я это как-то не учел. Но, ИМХО, это ближе к предварительной оптимизации по скорости, нежели к реальному преимуществу при написании кода.
Гвидо отверг идею, заявив, что строковых констант будет достаточно для любого приложеиня.
Вообще обзор больше со стороны GUI разработки под Windows. При веб-разработке под UNIX было бы другие плюсы-минусы.
А меня больше всего раздражает невозможность написать в питоне some_list.len(), some_list.each… и обязательные скобки при вызове метода. Но это все конечно мелочи если вы привыкли к такому подходу :)
Неплохая статья на эту тему.
Автор явно яррый питонист.
Позвольте мне усомниться.
Это что такое? Неужели никто не заметил?
Наверное имелось в виду
И ретурн там вопиюще лишний.
Основываясь на собственном многолетнем опыте использования обоих языков…
Позвольте мне усомниться.
Это что такое? Неужели никто не заметил?
def foo( ** kargs )
return kargs[ :first ] + kargs[ :second ]
end
Наверное имелось в виду
def foo args = {}
args[:first] + args[:second]
end
И ретурн там вопиюще лишний.
Это опечатка, такое бывает. Когда знаешь более двадцати языков программирования, иногда клинит даже на синтаксисе тех, которые используешь часто. А скобочки и return я написал для иллюстративности — чтобы сравнивать тот синтаксис про который я рассказываю, на не ассортимент возможностей по упрощению синтаксиса.
def foo args = {}
Возможность не ставить скобки — как кунгфу, не надо использовать её без необходимости.
Был бы ярым питонистом — писал бы по PEP8.
ну тогда исправьте пожалуйста, глазам больно :)
спасибо
спасибо
и не одного комментария про Perl?
multiproccessing позволяет обойти GIL в python
Используются настоящие потоки операционной системы. Несмотря на то, что оба языка используют GIL (global interpreter lock), использование настоящих потоков позволят коду на Python выполнять в отдельных потоках блокирующие операции — например, вызов shell скрипта или функций операционной системы — и при этом не блокировать другие потоки. В Ruby до версии 1.9 использовался один настоящий поток, а переключение между потоками языка эмулировалось. На практике это приводит к тому, что если в отдельном потоке Ruby вызвать shell скрипт (например, копирование файлов) или функцию операционной системы (например, показать окошко с сообщением) — то все остальные потоки в данном скрипте останавливались. Начиная с версии 1.9 Ruby использует настоящие потоки операционной системы, но на данный момент (версия 1.9.3-p125) множество недоработок не позволяют получить от этого преимущество — в частности, Ruby крайне не любит поднимать GIL при вызовах блокирующих операций, так что попытка показать окно операционной системы в отдельном потоке так же остановит остальные — на этот раз потому, что не будет поднят GIL.
wiki.python.org/moin/GlobalInterpreterLock
В питоне тоже не все чисто с ним.
В частности при работе с CPU intensive будет блокироваться GIL, а следовательно ВСЕ треды на процессорном ядре, где запущен питон процесс.
В этом плане, вплоть до 3.2 версии питона лучше, легче и удобнее использовать вместо тредом greenlets, stackless, eventlet и аналоги.
wiki.python.org/moin/GlobalInterpreterLock
В питоне тоже не все чисто с ним.
В частности при работе с CPU intensive будет блокироваться GIL, а следовательно ВСЕ треды на процессорном ядре, где запущен питон процесс.
В этом плане, вплоть до 3.2 версии питона лучше, легче и удобнее использовать вместо тредом greenlets, stackless, eventlet и аналоги.
Что есть «CPU intensive»? Два запущенных потока с числодробилками вполне себе псевдопараллельно выполняются, контексты переключаются достаточно резво.
Для тех кто пока только присматривается к Ruby или Python есть неплохая таблица сравнения синтаксиса 4х языков — Ruby, Python, Perl, PHP
http://hyperpolyglot.org/scripting
http://hyperpolyglot.org/scripting
А что насчет менеджера пакетов (rubygems)? Есть нечто подобное в Python сейчас? Также неплохо было бы узнать насчет community — у кого больше? По-мойму, здесь оба пункта добавляют плюсов к ruby.
Недавно был опрос c заголовком «Какой ваш любимый язык программирования?» на сайте Hacker News, где к слову, тусят восновном все американские стартапперы.
Так питон лидировал с большим отрывом.
Так питон лидировал с большим отрывом.
И так, продолжаем флеймообразующую тему, начатую в статье…
(знал же что не нужно заходить — не сдержусь)
К выборочным пунктам:
Именованные аргументы:
(defun foo (&key first second)
(+ first second))
(foo :first 2 :second 3)
функции-объекты:
(defun foo ()
(princ «test»))
(setf a #'foo)
(funcall a)
Интерполяция строк есть в библиотеке cl-interpol. Выглядит как-то так:
(princ #«My name is $name»)
Декораторы тоже на ридер макросах где-то есть. Выглядит как-то так:
#@threadsafe
(defun foo ()
(princ «I'm decorated»))
Но вообще декораторы почти не нужны, т.к. есть макросы. Как-то так:
(defun foo ()
(with-lock ()
(princ «I'm decorated»)))
Было бы интересно посмотреть на примеры реализации на Ruby или Python подобного уровня фич *в библиотеках*.
Всё, простите за выбор наугад пунктов и синтаксис от балды (в cl-interpol, например, наверняка другой), пора бежуть.
(знал же что не нужно заходить — не сдержусь)
К выборочным пунктам:
Именованные аргументы:
(defun foo (&key first second)
(+ first second))
(foo :first 2 :second 3)
функции-объекты:
(defun foo ()
(princ «test»))
(setf a #'foo)
(funcall a)
Интерполяция строк есть в библиотеке cl-interpol. Выглядит как-то так:
(princ #«My name is $name»)
Декораторы тоже на ридер макросах где-то есть. Выглядит как-то так:
#@threadsafe
(defun foo ()
(princ «I'm decorated»))
Но вообще декораторы почти не нужны, т.к. есть макросы. Как-то так:
(defun foo ()
(with-lock ()
(princ «I'm decorated»)))
Было бы интересно посмотреть на примеры реализации на Ruby или Python подобного уровня фич *в библиотеках*.
Всё, простите за выбор наугад пунктов и синтаксис от балды (в cl-interpol, например, наверняка другой), пора бежуть.
ИМХО, в пользу руби играет то, что это очень маленький язык (классы, методы, замыкания, массивы, хэши), и справочник его стандартных классов лаконичен. Python же очень сложно осилить, т.к. он большой и его документация — разбухшая, и в ней трудно найти что-то нужное.
Кстати, пример с
rescue
для руби неправильный.File.delete('file.txt') rescue Errno::ENOENT
на самом деле словит ЛЮБОЙ эксепшен и вернет Errno::ENOENT
. Другое дело что тут врядли что-то другое может появиться, но все же, возврат объекта эксепшена — не то что подразумевалось.Вот это уже гораздо интереснее, я этот подход откуда-то скопировал и не удосужился проврить что все работает. А можно в такой нотации отловить только нужное исключение?
как один из вариантов:
def method_a
# ...
File.delete('file.txt')
# ...
rescue Errno::ENOENT
# handle Errno::ENOENT
rescue AnotherYetError
# another yet handling
end
данная нотация используется только в том случае, если необходимо обязательно получить результат
content = File.read('file.txt') rescue "" # получим пустую строку, если файла нет
На счет многопоточности: то есть на многоядерном процессоре потоки, созданные в Ruby, автоматически распараллеливаются только если версия Ruby — 1.9.х? То есть до этого все выполнялись бы на одном ядре поочередно? =/ Как-то даже странно, учитывая что язык используется для high load проектов достаточно активно.
Нужно сделать один веб-проект. Питон знал поверхностно, Руби не знал совсем. Но так меня пробесило, что до сих пор Джанго не поддерживает 3й Питон (сколько ему уже лет?!), что решил выучить Руби и писать на рельсах…
Python vs Ruby