Ruby: больше гибкости, чем Java / C #? - PullRequest
3 голосов
/ 01 января 2009

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

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

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

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

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

Ответы [ 6 ]

8 голосов
/ 01 января 2009

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

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

4 голосов
/ 01 января 2009

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

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

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

В ответ на динамический ввод PHP:

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

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

1 голос
/ 16 октября 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 может делать нечто подобное с помощью Functors, но я не знаю достаточно, чтобы комментировать. Консенсус, который я видел в блогах или аналогичных программах, заключается в том, что Java делает это настолько ужасно сложным, что вы просто получите кровотечение из носа, просто попробовав это.

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

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

1 голос
/ 01 января 2009

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

0 голосов
/ 01 января 2009

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

0 голосов
/ 01 января 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...