Я не збирався розміщувати це як відповідь, але Xeoncross попросив мене, тож ми переходимо:
(Sidenote: якщо хтось міг би вирішити проблему розмітки у прикладі маленького коду, я би вдячний.)
Ерік Макс Френсіс написав:
"Брендон Дж. Ван Кожен" писав:
Що краще в Ruby ніж Python? Я впевнений, що є щось. Що це? Хіба не було б набагато більше сенсу запитати у цього Рубі людей, а не людей Python?
Можливо, чи не може, залежно від своїх цілей - наприклад, якщо цілі включають "соціологічне дослідження" спільноти Python, то поставлення запитань до цієї спільноти, ймовірно, виявить більше розкриття інформації про неї, ніж їх розміщення в іншому місці :-). Особисто я із задоволенням скористався можливістю переглядати одноденний підручник «Рубі» Дейва Томаса нарешті в OSCON. Нижче тонкого шпону різниць синтаксису я знаходжу Ruby та Python напрочуд схожими - якби я обчислював мінімальну діапазон дерев серед майже будь-яких мов, я впевнений, що Python та Ruby були б першими двома листами проміжний вузол :-).
Звичайно, я втомитися, в Ruby, щоб друкувати дурний «кінець» в кінці кожного блоку (а не просто unindenting) - але тоді я отримати , щоб уникнути друкуючи однаково дурні , :
який Python вимагає в
початку з кожен блок, так що це майже помивка :-). Інші відмінності в синтаксисі, такі як @fooversus
self.fooабо вища значимість випадку у Ruby vs Python, для мене насправді так само не мають значення.
Інші, без сумніву, ґрунтують свій вибір мови програмування саме на таких питаннях, і вони породжують найгарячіші дебати - але, на мою думку, це лише приклад одного із законів Паркінсона в дії (сума дебатів щодо певного питання обернено пропорційна рівню випуску). фактичне значення). Одна синтаксична різниця, яку я вважаю важливою, і на користь Python - але інші люди, без сумніву, думають просто навпаки - це "як ви називаєте функцію, яка не приймає жодних параметрів". У Python (як у C) для виклику функції ви завжди застосовуєте "оператор виклику" - кінцеві дужки безпосередньо після об'єкта, який ви викликаєте (всередині цих кінцевих дужок йдуть аргументи, які ви передаєте під час виклику - якщо ви не передаєте аргументів, тоді дужки порожні). Це залишає просту згадку про будь-який об'єкт без участі жодного оператора, оскільки це означає лише посилання на об'єкт - у будь-якому контексті, без особливих випадків, винятків, спеціальних правил тощо. У Ruby (як у Pascal) для виклику функції З аргументами ви передаєте аргументи (як правило, в дужках, хоча це не завжди), АЛЕ якщо функція не бере аргументів, то просто згадування про функцію неявно називає її. Це може виправдати очікування багатьох людей (принаймні, без сумніву, тих, чий єдиний попередній досвід програмування був з Паскалем, або іншими мовами з подібними "невмілими дзвінками", такими як Visual Basic) - але для мене це означає проста згадка про об'єкт може ВСІГО означати посилання на об'єкт АБО дзвінок на об'єкт, залежно від типу об'єкта - і в тих випадках, коли я не можу отримати посилання на об’єкт, просто згадуючи його, мені потрібно буде використовувати явне "дайте мені посилання на це, НЕ називайте!" операторів, які не потрібні інакше. Я відчуваю, що це впливає на "першокласність" функцій (або методів чи інших об'єктів, що дзвоняться) та можливість плавного обміну об'єктами. Тому для мене ця специфічна синтаксична різниця є серйозною чорною позначкою щодо Рубі - але я розумію, чому інші поступатимуться інакше, хоча я навряд чи можу з ними більше погодитися :-). Нижче синтаксису ми стикаємося з деякими важливими відмінностями елементарної семантики - наприклад, рядки в Ruby - це змінні об'єкти (як, наприклад, у C ++), тоді як у Python вони не змінюються (як у Java, або я вважаю, C #). Знову ж таки, люди, які судять передусім за тим, що вони вже знайомі, можуть подумати, що це є плюсом для Рубі (якщо, звичайно, вони не знайомі з Java або C #, звичайно :-). Мені здається, непорушні рядки - це відмінна ідея (і я не здивований, що Java, незалежно, я думаю, винаходила цю ідею, яка вже була в Python), хоча я не заперечувала б і з типом "мутаційний буфер струнів" (і в ідеалі - з кращою зручністю у використанні, ніж власні "рядкові буфери" Java); і я не даю цього судження через знайомість - перед вивченням Java, крім функціональних мов програмування, де люди, які судять головним чином за тим, що вони вже знайомі, можуть подумати, що це плюс для Рубі (якщо, звичайно, вони не знайомі з Java або C #, звичайно :-). Мені здається, непорушні рядки - це відмінна ідея (і я не здивований, що Java, незалежно, я думаю, винаходила цю ідею, яка вже була в Python), хоча я не заперечувала б і з типом "мутаційний буфер струнів" (і в ідеалі - з кращою зручністю у використанні, ніж власні "рядкові буфери" Java); і я не даю цього судження через знайомість - перед вивченням Java, крім функціональних мов програмування, де люди, які судять головним чином за тим, що вони вже знайомі, можуть подумати, що це плюс для Рубі (якщо, звичайно, вони не знайомі з Java або C #, звичайно :-). Мені здається, непорушні рядки - це відмінна ідея (і я не здивований, що Java, незалежно, я думаю, винаходила цю ідею, яка вже була в Python), хоча я не заперечувала б і з типом "мутаційний буфер струнів" (і в ідеалі - з кращою зручністю у використанні, ніж власні "рядкові буфери" Java); і я не даю цього судження через знайомість - перед вивченням Java, крім функціональних мов програмування, де Я думаю, що незмінні рядки - це відмінна ідея (і я не здивований, що Java, незалежно, я думаю, винаходила цю ідею, яка вже була в Python), хоча я не заперечувала б і за типом "мутаційний буфер струнів" (і в ідеалі - з кращою простотою у використанні, ніж власні "буферні рядки" Java; і я не даю цього судження через знайомість - перед вивченням Java, крім функціональних мов програмування, де Я думаю, що незмінні рядки - це відмінна ідея (і я не здивований, що Java, незалежно, я думаю, винаходила цю ідею, яка вже була в Python), хоча я не заперечувала б і за типом "мутаційний буфер струнів" (і в ідеалі - з кращою простотою у використанні, ніж власні "буферні рядки" Java; і я не даю цього судження через знайомість - перед вивченням Java, крім функціональних мов програмування, девсі дані незмінні, усі мови, які я знав, мали мінливі рядки - але коли я вперше побачив ідею незмінної струни на Java (яку я навчився добре ще до того, як пізнав Python), це одразу ж вразило мене відмінно, дуже добре підходить для референтна семантика мови програмування вищого рівня (на відміну від значення-семантики, яка найкраще підходить для мов, ближчих до машини та далі від додатків, таких як C) із рядками як першокласного, вбудованого (і досить вирішальний) тип даних.
У елементарної семантики у Рубі є деякі переваги - наприклад, вилучення «списків проти кортежів» Питона надзвичайно тонкою відмінністю. Але в основному оцінка (як я вважаю, простота, великий плюс і тонкі, розумні розрізнення, помітний мінус) проти Рубі (наприклад, з закритими і напіввідкритими інтервалами, з позначеннями a..b і .. .b [хтось хоче стверджувати, що очевидно, що є? -)], нерозумно - ІМХО, звичайно!). Знову ж таки, люди, які вважають, що в основі мови багато подібних, але тонко різних речей, ПЛЮС, а не МІНУС, звичайно, будуть рахувати це "навпаки" від того, як я їх рахую :-).
Нехай вас не вводить в оману ці порівняння думок, що ці дві мови є
дужеінший, зауважте. Вони ні. Але якщо мене попросять порівняти "capelli d'angelo" з "spaghettini", після того, як зазначив, що ці два види макаронів майже не відрізняються ні від кого і є взаємозамінними в будь-якій страві, яку ви хочете приготувати, я б тоді неминуче мав перейти до мікроскопічного дослідження того, як непомітно відрізняються довжини і діаметри, як кінці пасм звужуються в одному випадку, а не в іншому, і так далі - спробувати і пояснити, чому я особисто вважаю за краще "ангело, як макаронні вироби в будь-якому вигляді бульйону, але вважає за краще спагеттіні, як макаронні вироби, щоб їхати з підходящими соусами для таких довгих тонких макаронних форм (оливкова олія, фарш з часнику, фарш з червоного перцю і дрібно натертий анчоус, наприклад - але якщо ви нарізали часник і перець замість того, щоб фаршувати їх, то вибирайте тіло спагетті, а не більш тонке просочення спагетіні, і було б радимо відмовитися від ачворку і замість цього додати трохи свіжого весняного базиліка [ чи навіть - я єретик ...! - легка м'ята ...] листя - в самий останній момент перед подачею страви). Ой, вибачте, це свідчить про те, що я подорожую за кордон і мабуть не маю макаронних виробів певний час. Але аналогія все-таки досить хороша! -) і було б радимо відмовитися від ачхов'ю і додати замість нього свіжий весняний базилік [або навіть - я єретик ...! - легка м'ята ...] листя - в самий останній момент перед подачею страви). Ой, вибачте, це свідчить про те, що я подорожую за кордон і мабуть не маю макаронних виробів певний час. Але аналогія все-таки досить хороша! -) і було б радимо відмовитися від ачхов'ю і додати замість нього свіжий весняний базилік [або навіть - я єретик ...! - легка м'ята ...] листя - в самий останній момент перед подачею страви). Ой, вибачте, це свідчить про те, що я подорожую за кордон і мабуть не маю макаронних виробів певний час. Але аналогія все-таки досить хороша! -)
Отже, повертаючись до Python та Ruby, ми переходимо до двох великих функцій (з точки зору належної мови - залишення бібліотек та інших важливих допоміжних допоміжних засобів, таких як інструменти та середовища, як вставляти / розширювати кожну мову тощо, тощо) з це поки що - вони все одно не застосовуватимуться до всіх ВПРОВАДЖЕНЬ кожної мови, наприклад, Jython проти Classic Python є двома реалізаціями мови Python!):
Ітератори та кодові блоки Ruby проти ітераторів та генераторів Python;
ВСЬОГО Рубі, нестримна "динамічність", включаючи можливість "відкрити" будь-який існуючий клас, включаючи всі вбудовані, та змінити свою поведінку під час виконання - проти величезної, але обмеженої
динаміки Python , яка ніколи не змінює поведінку існуючих вбудовані класи та їх екземпляри.
Особисто я вважаю 1 мийкою (відмінності настільки глибокі, що я міг легко бачити людей, що ненавидять будь-який підхід і зворотний інший, але на моїх особистих масштабах плюси і мінуси майже рівномірно); і [2] важливе питання - той, що робить Ruby набагато більш придатним для "майстерності", але НЕ Python однаково більш придатний для використання у великих виробничих додатках. Це певним чином смішно, тому що обидві мови настільки динамічніші, ніж більшість інших, що врешті-решт ключова різниця між ними від моєї POV повинна залежати від цього - що в цьому відношенні Рубі "переходить до одинадцяти" (посилання тут, звичайно, "Спинальний дотик". У Рубі,Я можу це зробити ! Тобто я можу динамічно змінювати вбудований клас рядків так, щоб
a = "Привіт, світ"
b = "привіт світ"
якщо a == b
друк "рівний! \ n"
ще
надрукувати "інше! \ n"
кінець
БУДЕ друкувати "рівним". У python немає способу зробити це. Для метапрограмування, реалізації експериментальних рамок тощо, ця дивовижна динамічна здатність Рубі надзвичайно надзвичайна
привабливий. АЛЕ - якщо ми говоримо про великі програми, розроблені багатьма людьми та підтримувані ще більше, включаючи всі види бібліотек з різних джерел, і потрібно запускати у виробництво на клієнтських сайтах ... ну, я НЕ ХОЧУ мова, ЯКА ЦІ ТИНА динамічна, дуже дякую. Я ненавиджу саму ідею, що деякі бібліотеки мимоволі ламають інші непов'язані між собою ті, що покладаються на те, що ці рядки відрізняються - ось такий тип "глибокого та глибоко прихованого" каналу "між фрагментами коду, який ЛОКУВАТЬСЯ і повинен бути окремим, що заклинає смерть у широкомасштабне програмування. Дозволяючи будь-якому модулю впливати на поведінку будь-якого іншого "приховано",
Якби мені довелося використовувати Ruby для такої великої програми, я б спробував покластися на обмеження стилю кодування, безліч тестів (щоб їх повторювати, коли що-небудь змінилося - навіть те, що повинно бути абсолютно не пов’язаним між собою ...) тощо. заборонити використання цієї мовної функції. Але, на перший погляд, НЕ мати цю функцію - це навіть краще - так само як Python був би ще кращою мовою для програмування прикладних програм, якби певна кількість вбудованих модулів могла бути "прибитими", тому я ЗНАЮ, що , наприклад,
len("ciao")4 (замість того, щоб турбуватися підсвідомо про те, чи хтось змінив прив'язку імені lenв __builtins__
модулі ...). Я сподіваюся, що врешті-решт Python "прибити" свої вбудовані модулі.
Але проблема незначна, оскільки перезавантаження вбудованих модулів є досить застарілою, а також рідкісною практикою в Python. У Ruby це вражає мене як головного - так само, як занадто потужні
макро-засоби інших мов (наприклад, Ділан) представляють подібні ризики на мою власну думку (я сподіваюся, що Python ніколи не отримає такої потужної макросистеми, ні Незважаючи на привабливість "дозволити людям визначати свої власні доменні маленькі мови, вбудовані в саму мову" - це, IMHO, погіршить чудову корисність Python для програмування прикладних програм, представивши "привабливу неприємність" потенційному майстру, який ховається в серці кожного програміста ...).
Олексій