Oт C/C++ към Ruby

Трудно е да се напише кратко описание за разликите между Ruby и C/C++. Ще споменем само, че Ruby е писан на C, преди да дадем приликите и разликите.

Прилики със C

Както в C, така и в Ruby …

  • Можете да програмирате процедурно (въпреки това кода ви ще бъде ОО под повърхността ).
  • Повечето оператори са същите. Липсват обаче ++ или --.
  • Имаме __FILE__ и __LINE__.
  • Съществуват константи, но не използваме ключовата дума const. В Ruby константите се започват с главна буква.
  • Низовете са оградени с двойни кавички.
  • Низовете могат да се променят.
  • В Ruby имаме ri команда в терминала, по подобие на man.
  • Наличен е подобен команден дебъгер.

Прилики със C++

Както в C++, така и в Ruby …

  • Имаме повечето оператори ( дори :: ). << е често използван за добавянето на елементи в списък. Забележка: в Ruby използваме . вместо ->.
  • public, private и protected изпълняват подобна роли.
  • Наследяването става с един символ, но той не е :, а <.
  • Можете да слагате кода си в “модули”, подобно на именованите пространства в C++.
  • Изключенията работят подобно, въпреки че ключовите думи са други.

Разлики със C

За разлика от C, в Ruby …

  • Обектите са strongly typed ( имената на променливите нямат тип ).
  • Липсват макроси и препроцесорни директиви, кастване и указатели, typedefs, sizeof или enums.
  • Липсват заглавни файлове. Просто дефинирате функции ( обикновено наричани “методи” ) и класове.
  • Липсва директивата #define. В Ruby използваме директно константите.
  • В Ruby 1.8 кода се интерпретира в реално време, а не се компилира до машинен или byte код.
  • Всички променливи живеят в heap-а. Няма нужда от ръчното освобождаване на памет – за това се грижи garbage collector-а.
  • Аргументите към методите се предават по референция, не по стойност.
  • В Ruby използваме require 'foo' вместо #include <foo> или #include "foo".
  • Нямаме достъп до асемблерския код.
  • Не използваме ; за край на ред.
  • Можем да ползваме if и while без скоби.
  • Скобите при извикването на метод могат да бъдат пропуснати.
  • Обикновено не ползваме къдрави скоби—слагаме край на много редовите конструкции ( като while ) с ключовата дума @end.
  • Ключовата дума do се използва за блоковете .
  • Понятието “блок” има различно значение. В Ruby блока е част от код, асоциирана с тяло на метод, израз или др.
  • Няма декларация на типа на променливите. Просто ги наименоваме при употребата.
  • Когато тестваме за истинност, само false и nil ни дават лъжа. Всичко друго се приема за истина ( включително 0, 0.0 и "0").
  • Няма char—в Ruby това е еднобуквен низ.
  • Низовете не завършват с нулиращ байт.
  • Масивите могат да се разширяват динамично, когато добавяме елементи.
  • Много често всичко е израз.

Разлики със C++

За разлика от C++, в Ruby …

  • Липсва явни референции, Това е така, защото в Ruby всяка променлива автоматично се свързва с обект.
  • Обектите са strongly, но dynamically typed. При runtime се разбира дали един метод може да бъде извикан.
  • Конструктора е наименован initialize.
  • Всички методи са винаги виртуални.
  • Клас променливите винаги започват с @@.
  • Нямаме директен достъп до член променливите ( наричани атрибути )—това става с методи.
  • Използваме self вместо this.
  • Някои методи завършва с ’?’ или ’!’. Те всъщност не са специални, а това е част името им. Наименоваме метод, който завършва с ’?’, ако той връща булев резултат, а ’!’ когато метода променя състоянието на променливите.
  • Нямаме множествено наследяване. За сметка на това имаме “mixins” ( може да наследим всички методи на даден модул ).
  • Имаме няколко задължителни конвенции за именоване ( пример: имената на класовете започват с главна буква, имената на променливите започват с малко буква ).
  • Не е задължително да ползваме скоби при извикването на метод.
  • Може да отворим клас по всяко време за добавяне на методи.
  • Нямаме нужда от C++ templates.
  • Итерацията се извършва по различен начин. В Ruby не е нужна употребата на отделен обект за итерацията ( като vector<T>::const_iterator iter), а може да направим един обект итерационен, ако дефинираме метод each, , който ще ни позволи да ползваме модула Enumerator.
  • Налични са два типа контейнери: масиви and хешове.
  • Нямаме конвертиране на типове.
  • Многонишковата библиотека е вградена, но за разлика то 1.9, в 1.8 имаме “green threads”, а не native threads.
  • Unit testing библиотеката идва със стандартната библиотека на Ruby.