Ruby: больше гибкости, чем у Java / C#?

Это то, что я новичок в изучении Ruby, или у него действительно больше способов писать (одинаковые) вещи, чем на Java / C#? Кроме того, если он более гибкий, чем Java, существуют ли какие-либо лингвистические особенности Ruby, которые обычно используются нет, чтобы избежать путаницы?

Примерами могут быть параллельное присваивание и, возможно, все разные способы написания строк?

Примечание: Я не прошу сравнения с Java / C# ... просто вопрос по этому языку, пожалуйста ...

Редактировать: Я понимаю, что C#, Java и Ruby строго типизированы и что только Ruby (например, Python и другие) является динамически типизированным (в то время как Java / C# типизируется статически). В некоторых ответах говорится, что языки с динамической типизацией более гибкие. Обязательно ли это правда и как это влияет на синтаксис? Я спрашиваю только о синтаксической гибкости.

(PHP также динамически типизирован, и, насколько я видел, нет кажется более гибким, чем Java / C#. Опять же, я имею в виду синтаксис, а не развертывание или какой-либо другой аспект ...)

Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
3
0
993
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ruby - динамический язык. C# и Java являются статически типизированными языками со строгой типизацией. C# в версии 4.0 добавит динамические функции, но до сих пор у Java и C# была совершенно другая и более строгая парадигма, чем у динамических языков, таких как Ruby и Python.

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

Dan Rosenstark 01.01.2009 10:49

На самом деле нет. Это не статически типизировано. Динамическая типизация означает, что переменная не привязана к определенному типу во время компиляции. Значит, тип может измениться. Природа динамической типизации и динамической диспетчеризации дает языкам выдающуюся гибкость, которая менее заметна в статических языках.

mmx 01.01.2009 10:53

Чтобы уточнить, «var x = 5;» в C# статически типизирован, даже если вы не сказали «int x = 5;», C# компилятор выведет его во время компиляции, а «x» будет «int» в обоих случаях. В динамических языках дело обстоит иначе.

mmx 01.01.2009 10:54

Да, Ruby строго типизирован, но строго типизирован! = Статически типизирован. В Java переменные имеют типы - в Ruby значения имеют типы.

Rene Saarsoo 01.01.2009 10:57

Рене, точно. Это было то, что я очень старался сказать, ваше заявление было простым и отличным!

mmx 01.01.2009 11:01

Спасибо, Мердад. Я до сих пор не понимаю, как ваш ответ на самом деле отвечает на вопрос. Ruby не имеет статической типизации, в отличие от C# / Java. Все три строго типизированы. Так?

Dan Rosenstark 01.01.2009 18:12

Ruby не имеет типа статически, в то время как C# / Java. Динамическая типизация позволяет отложить множество проверок до времени выполнения и не беспокоить программиста во время компиляции о неразрешенных ссылках на методы или подобных вещах.

mmx 02.01.2009 08:48

Есть разница между «статически типизированным» и «строго типизированным». Python имеет динамическую типизацию, но также и строго типизирован. Такие языки, как PHP, слабо типизированы, что означает, что тип меняется в зависимости от контекста. Например, добавление двух числовых строк может дать число.

Soviut 04.01.2009 03:24

Все языки с динамической типизацией (например, Ruby) обычно более гибкие, чем языки со статической типизацией (например, Java). Вам не нужно бороться с системой типов, что вы часто делаете в статически типизированных языках.

Другой динамический язык, очень похожий на Ruby, - это Python. Однако в Дзен Python одно из правил гласит, что «должен быть один и только один способ что-то делать». Это полная противоположность Ruby, которая допускает столько метапрограммирования, что существует практически бесконечное количество способов сделать то же самое.

Тем не менее, это несколько иронично, что до Python 3.0 (он же 3000) строковые значения и значения Unicode были разными типами. Хотя это имеет смысл, люди иногда сталкиваются с проблемами, когда они много конвертируют между ними для выполнения текстовых операций.

Если у вас есть выбор, я бы почти рекомендовал использовать Python в качестве введения в динамические языки. В Ruby нет ничего плохого, но вы можете столкнуться с меньшим количеством ситуаций, когда «правильный» способ сделать что-то не совсем очевиден.

В ответ на динамическую типизацию PHP:

Система типов PHP является гибкой, позволяя автоматически преобразовывать типы в зависимости от того, в каком контексте они используются. Однако на самом деле это не делает настоящие динамические типы. Сам язык в основном статичен и не позволяет добавлять атрибуты к объектам, например, во время выполнения (по крайней мере, в последний раз, когда я проверял).

Python и, вполне возможно, Ruby на самом деле строго типизированы, что означает, что вы можете уверенно проводить сравнение типов и не можете использовать PHP-трюки, такие как добавление числовых строк для получения числа. Истинные динамические языки также часто допускают мета-класс, где вы можете настроить тип экземпляра или класса или добавить атрибуты к любому из них во время выполнения.

Спасибо. Замечательный и отличный ответ. А как насчет сравнения с нединамическими языками, такими как Java и C#? [У меня нет выбора: меня «заставляют» использовать Ruby и Rails.]

Dan Rosenstark 01.01.2009 18:09

Также позвольте мне упомянуть, что, хотя это не по теме, у Ruby есть Rails, а у Python есть миллион различных вариантов, включая DJango. И я думаю, что в наши дни наличие Бога чего-то стоит.

Dan Rosenstark 02.01.2009 06:10

На мой взгляд, наиболее часто используемые функции в Ruby и отсутствующие в Java - это блоки кода / лямбда-выражения / замыкания.

Еще одна замечательная (но, возможно, опасная) функция - это открытые классы - вы можете изменить любой класс, который хотите - добавить новый метод, изменить старый и т.д. Вы даже можете добавить метод к конкретному объекту, а не ко всему классу :).

Слово для описания второго абзаца - метапрограммирование. не критикуя вас, это хорошее объяснение, просто добавляя свои мысли.

andHapp 01.01.2009 14:00

Отличный ответ. Не могли бы вы привести крошечный пример блока / лямбда / закрытия? Кроме того, что вы лично НЕ используете в Ruby, потому что это слишком опасно? Спасибо за Ваш ответ.

Dan Rosenstark 01.01.2009 18:19

Очень часто вы хотите предоставить методу данные, которые влияют на его результат. Что, если бы вы могли таким же образом снабдить метод процедурой? Очень хорошая статья под названием "Может ли ваш язык программирования это делать?" особенности блога JoelOnSoftware; joelonsoftware.com/items/2006/08/01.html

deau 14.10.2009 20:47
Ответ принят как подходящий

Я не знаю Java или C#, но позволяю тому факту, что вы можете переопределить, как + работает с числами, говорит сам за себя.

Что он говорит, когда говорит сам за себя? «Я не существую на Java, используйте меня с осторожностью?»

Dan Rosenstark 01.01.2009 18:19

Или это «как и я, есть целый ряд других гибких функций Ruby, которых нет в Java / C#?»

Dan Rosenstark 01.01.2009 18:24

Я прокомментировал ответ rkj выше относительно лямбды. Этот код демонстрирует запрошенный вами пример;

def abs(n); (n < 0) ? -n : n; end
def square(n); n * n; end
def average(x, y); (x + y) / 2; end

def fixed_point(x, point, process, test)
  return point if test.call(x, point)
  fixed_point(x, process.call(x, point), process, test)
end

def sqrt(n)
  process = lambda {|n,g| average g, (n/g) }
  test = lambda {|n,g| abs(square(g) - n) < 0.001} 
  fixed_point(n, 1.0, process, test)
end

Первое, на что следует обратить внимание, это то, что метод fixed_point реализует общую идею постепенного применения процесса к некоторым данным, пока они не пройдут определенный тест. Функция sqrt определяет процесс нахождения квадратного корня и тест, чтобы определить, когда мы должны быть удовлетворены. Эти «процедуры» затем передаются так же, как и любая другая форма данных, так что fixed_point может творить чудеса.

Вместо временного сохранения процесса и тестирования все это может быть анонимным. Мы могли бы переписать sqrt как;

def sqrt(n)
  fixed_point( n, 1.0, 
      lambda {|n,g| average g, (n/g)},
      lambda {|n,g| abs(square(g) - n) < 0.001} )
end

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

Конечно, другой вариант, который предлагает Ruby, - это метапрограммирование. Я мог бы переписать sqrt так, чтобы он перезаписывал (на лету) fixed_point, используя правильный процесс и тест, но это, вероятно, злоупотребление функцией :-)

пс. Размещенная ссылка на JoelOnSoftware заслуживает повторения; http://www.joelonsoftware.com/items/2006/08/01.html

Спасибо за это. Мне придется перечитать это после сна. Я отмечу одну вещь: ламба и блоки симпатичны, но неанонимные функции выполняют ОГРОМНУЮ функцию: они дают имена блокам кода ... реальные имена с реальными именами ЛОКАЛЬНЫХ переменных. Это упрощает понимание кода, и это хорошо (при условии, что он по сути эквивалентен) ... в любом случае, я буду комментировать больше, когда проработаю этот материал с фиксированной точкой.

Dan Rosenstark 19.10.2009 05:11

Замечательный материал, спасибо за это. Я действительно думаю, что часть этого синтаксического сжатия (например, ваш последний метод sqrt) приводит к тому, что код использует меньше символов, но менее читабелен и НЕ более эффективен. Лямбды определены, но не присваиваются переменным. Я УГАДАЮ, что для Ruby это то же самое (скажем, для эффективности), но код не так удобочитаем. Если вы не играете в гольф-код, я предпочитаю определять переменные всякий раз, когда это имеет смысл. В любом случае спасибо и +1.

Dan Rosenstark 19.10.2009 14:49

Другие вопросы по теме