В Ruby из C и C++

Довольно трудно составить список того, как ваш код на С или С++ будет отличаться от кода на Ruby - это различие весьма значительно. Первопричина этого - множество возможностей runtime в Ruby. Ruby - это выдающийся антагонист принципу “нет ничего неявного” в С и это является ключевым моментов, делающим жизнь программиста легче за счет переноса основной работы в runtime. Пока вы не занимаетесь оптимизацией кода, нет необходимости удовлетворять “прихоти” компилятора.

Таким образом, с одной стороны, Ruby код выполняется намного медленнее “эквивалентного” C или C++ кода. С другой стороны, голова идет кругом от осознания того, насколько быстро можно “завести” Ruby программу и насколько мало строк кода для этого требуется. Ruby намного проще, чем C++, и “избалует” вас своими возможностями.

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

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

Конечно, сам Ruby написан на С.

Сходства с С

Как и в С, в Ruby…

  • можно программировать процедурно, если есть желание (но это все равно будет объектно-ориентировано “за кулисами”.
  • большинство операторов похожи (в том числе присвоение с вычислением и битовые операторы), но в Ruby нет ++ и --.
  • есть __FILE__ и __LINE__
  • можно объявлять константы, хотя и нет специального слова const - константность достигается соглашениями о наименовании (константы начинаются с заглавной буквы).
  • строки заключаются в кавычки.
  • строки мутабельны.
  • как и в случае с man-справочниками, можно читать документацию в терминале с помощью команды ri.
  • есть похожий консольный отладчик.

Сходства с С++

Как и в С++, в Ruby…

  • практически те же самые операторы (даже ::), << часто используется для добавления элемента в список, однако, в Ruby не используется ->, а просто ..
  • public, private и protected выполняют похожие функции.
  • для обозначения наследования используется один символ, но не :, а <.
  • код можно организовывать в модули по аналогии с namespace в C++.
  • похоже работают исключения, однако с другими ключевыми словами.

Отличия от С

В Ruby в отличие от C…

  • объекты строго типизированы (а переменные не имеют собственного типа).
  • отсутствуют макросы и препроцессоры, нет привидения типов, нет ни указателей, ни арифметики с ними, нет псевдонимов для типов, нет sizeof и перечислений.
  • нет файлов заголовков - вы просто пишите функции (называемые “методы”) и классы в файлах исходников.
  • нет #define - используйте константы.
  • начиная с Ruby 1.8 код интерпретируется в runtime, нежели компилируется в некий машинный или байт-код.
  • все переменные живут в “куче”, нет необходимости освобождать память - сборщик мусора сделает это за вас.
  • аргументы передаются в функции-методы по значению, где значения всегда ссылки.
  • вместо #include <foo> или #include "foo" пишется require 'foo'.
  • нельзя писать на ассемблере в коде.
  • нет точки с запятой в конце строк.
  • не нужны скобки вокруг выражения для if и while.
  • не обязательны скобки для обозначения вызова функций.
  • многострочные конструкции и циклы (например, while) принято завершат ключевым словом end, нежели заключать в фигурные скобки.
  • ключевое слово do используется для так называемых “блоков”, нет оператора do
  • понятие “блок” обозначает кусок кода, ассоциированный с вызовом метода, и внутри кода метода можно вызвать этот блок.
  • переменные не декларируются, а создаются “на лету” во время присваивания.
  • в тестах на истинность только nil и false интерпретируются как ложь, все остальное - истина (включая 0, 0.0 и "0").
  • отсутствует символ (“char”) - это просто односимвольная строка.
  • строки не оканчиваются нулевым байтом.
  • массив заключается в [], а не {}.
  • размер массива увеличивается автоматически при добавлении элемента.
  • при сложении массивов получается один большой массив (в “куче”, естественно) - нет необходимости заниматься арифметикой указателей.
  • практически все - выражение (например while возвращает RValue)

Отличия от C++

В Ruby в отличие от C++…

  • нет явного отличия для указателя - в Ruby любая переменная автоматически разыменовывается в объект.
  • объекты строго, но динамически типизированы. Работоспособность метода проверяется только в runtime.
  • Конструктор называется initialize, а не имя класса.
  • все методы виртуальные.
  • статические переменные (переменные класса) начинаются с @@ (например, @@total_widgets).
  • нет доступа к членам класса - доступ к ним (“атрибуты” в Ruby) возможен только через методы.
  • вместо this - self.
  • имена некоторых методов кончаются на “!” и “?”, и это действительно часть имени.
  • нет как такового множественного наследования, однако в Ruby есть “миксины” (“mixins”) (т.е. можно “унаследовать” методы от модуля).
  • имеются несколько ограничений по наименованию (например, имена классов начинаются с заглавной буквы, переменные - со строчной).
  • скобки для вызова метода не обязательны.
  • можно заново открыть класс и добавить в него методы.
  • нет необходимости в шаблонах (“templates”), т.к. можно присвоить переменной любой тип объекта, а типы все равно определяются в runtime) - нет и приведения типов.
  • итерация происходит несколько иным способом - в Ruby не надо использовать отдельный объект итератора (как vector<T>::const_iterator iter), а можно “подмешать” в класс модуль Enumerator и просто вызвать метод each.
  • есть всего 2 вида контейнеров - Array и Hash.
  • нет преобразований типов - в Ruby оно вам скорее всего не понадобится.
  • встроенная поддержка многопоточности, но в Ruby 1.8 это т.н. “green threads” (живущие только внутри интерпретатора), а не нативные системные треды.
  • Ruby поставляется со стандартной библиотекой для тестирования.