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

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

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

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

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

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


person Dan Rosenstark    schedule 01.01.2009    source источник


Ответы (6)


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

person August Lilleaas    schedule 01.01.2009
comment
Что он говорит, когда говорит сам за себя? Я не существую на Java, используйте меня с осторожностью? - person Dan Rosenstark; 01.01.2009
comment
Или, как и я, существует множество других гибких функций Ruby, которых нет в Java / C #? - person Dan Rosenstark; 01.01.2009

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

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

person rkj    schedule 01.01.2009
comment
Слово для описания второго абзаца - метапрограммирование. не критиковать вас, это хорошее объяснение, просто добавляя свои мысли. - person andHapp; 01.01.2009
comment
Отличный ответ. Не могли бы вы привести крошечный пример блока / лямбда / закрытия? Кроме того, что вы лично НЕ используете в Ruby, потому что это слишком опасно? Спасибо за Ваш ответ. - person Dan Rosenstark; 01.01.2009
comment
Очень часто вы хотите предоставить методу данные, которые влияют на его результат. Что, если бы вы могли таким же образом снабдить метод процедурой? Очень хорошая статья под названием "Может ли ваш язык программирования делать это?" особенности блога JoelOnSoftware; joelonsoftware.com/items/2006/08/01.html - person deau; 14.10.2009

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

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

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

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

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

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

person Soviut    schedule 01.01.2009
comment
Спасибо. Замечательный и отличный ответ. Как насчет сравнения с нединамическими языками, такими как Java и C #? [У меня нет выбора: я вынужден использовать Ruby и Rails.] - person Dan Rosenstark; 01.01.2009
comment
Также позвольте мне упомянуть, что, хотя это не по теме, у Ruby есть Rails, а у Python есть миллион различных вариантов, включая DJango. И я думаю, что в наши дни наличие Бога чего-то стоит. - person Dan Rosenstark; 02.01.2009

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

person mmx    schedule 01.01.2009
comment
Но Ruby тоже строго типизирован, верно? В любом случае, как это изменит ваши варианты? Это просто означает, что вам не нужно определять типы переменных ... нет? - person Dan Rosenstark; 01.01.2009
comment
На самом деле нет. Это не статически типизировано. Динамическая типизация означает, что переменная не привязана к определенному типу во время компиляции. Значит, тип может меняться. Природа динамической типизации и динамической диспетчеризации дает языкам выдающуюся гибкость, которая менее заметна в статических языках. - person mmx; 01.01.2009
comment
Чтобы уточнить, var x = 5; в C # статически типизирован, даже если вы не сказали int x = 5 ;, C # compiler сделает вывод во время компиляции, и x будет int в обоих случаях. В динамических языках дело обстоит иначе. - person mmx; 01.01.2009
comment
Да, Ruby строго типизирован, но строго типизирован! = Статически типизирован. В Java переменные имеют типы - в Ruby значения имеют типы. - person Rene Saarsoo; 01.01.2009
comment
Рене, точно. Это было то, что я очень старался сказать, ваше заявление было простым и отличным! - person mmx; 01.01.2009
comment
Спасибо, Мердад. Я до сих пор не понимаю, как ваш ответ на самом деле отвечает на вопрос. Ruby не имеет статической типизации, в отличие от C # / Java. Все три строго типизированы. Так? - person Dan Rosenstark; 01.01.2009
comment
Ruby не является статически типизированным, в отличие от C # / Java. Динамическая типизация позволяет отложить множество проверок до времени выполнения и не беспокоить программиста во время компиляции о неразрешенных ссылках на методы или подобных вещах. - person mmx; 02.01.2009
comment
Есть разница между статически типизированными и строго типизированными. Python имеет динамическую типизацию, но также и строго типизирован. Такие языки, как PHP, слабо типизированы, что означает, что тип меняется в зависимости от контекста. Например, добавление двух числовых строк может дать число. - person Soviut; 04.01.2009

Я прокомментировал ответ 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

person deau    schedule 16.10.2009
comment
Спасибо за это. Мне придется перечитать это после сна. Я отмечу одну вещь: ламба и блоки симпатичны, но неанонимные функции выполняют ОГРОМНУЮ функцию: они дают имена блокам кода ... реальные имена с реальными именами ЛОКАЛЬНЫХ переменных. Это упрощает понимание кода, и это хорошо (при условии, что он по сути эквивалентен) .... в любом случае, я прокомментирую больше, когда проработаю этот материал с фиксированной точкой. - person Dan Rosenstark; 19.10.2009
comment
Замечательный материал, спасибо за это. Я действительно думаю, что часть этого синтаксического сжатия (например, ваш последний метод sqrt) приводит к тому, что код использует меньше символов, но менее читаем и НЕ более эффективен. Лямбды определены, но не присваиваются переменным. Я УГАДАЮ, что для Ruby это то же самое (скажем, для эффективности), но код не так удобочитаем. Если вы не играете в гольф-код, я предпочитаю определять переменные всякий раз, когда это имеет смысл. В любом случае спасибо и +1. - person Dan Rosenstark; 19.10.2009

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

person Rene Saarsoo    schedule 01.01.2009