|
| 1 | +--- |
| 2 | +layout: page |
| 3 | +title: To Ruby From C and C++ |
| 4 | +--- |
| 5 | + |
| 6 | +It’s difficult to write a bulleted list describing how your code will be |
| 7 | +different in Ruby from C or C++ because it’s quite a large difference. |
| 8 | +One reason is that the Ruby runtime does so much for you. Ruby seems |
| 9 | +about as far as you can get from C’s “no hidden mechanism” principle—the |
| 10 | +whole point of Ruby is to make the human’s job easier at the expense of |
| 11 | +making the runtime shoulder more of the work. Unless or until you |
| 12 | +profile your code for optimization, you don’t need to care one whit |
| 13 | +about “keeping your compiler happy” when using Ruby. |
| 14 | + |
| 15 | +That said, for one thing, you can expect your Ruby code to execute much |
| 16 | +more slowly than “equivalent” C or C++ code. At the same time, your head |
| 17 | +will spin at how rapidly you can get a Ruby program up and running, as |
| 18 | +well as at how few lines of code it will take to write it. Ruby is much |
| 19 | +much simpler than C++—it will spoil you rotten. |
| 20 | + |
| 21 | +Ruby is dynamically typed, rather than statically typed—the runtime does |
| 22 | +as much as possible at run-time. For example, you don’t need to know |
| 23 | +what modules your Ruby program will “link to” (that is, load and use) or |
| 24 | +what methods it will call ahead of time. |
| 25 | + |
| 26 | +Happily, it turns out that Ruby and C have a healthy symbiotic |
| 27 | +relationship. Ruby supports so-called “extension modules”. These are |
| 28 | +modules that you can use from your Ruby programs (and which, from the |
| 29 | +outside, will look and act just like any other Ruby module), but which |
| 30 | +are written in C. In this way, you can compartmentalize the |
| 31 | +performance-critical parts of your Ruby software, and smelt those down |
| 32 | +to pure C. |
| 33 | + |
| 34 | +And, of course, Ruby itself is written in C. |
| 35 | + |
| 36 | +### Similarities with C |
| 37 | + |
| 38 | +As with C, in Ruby,... |
| 39 | + |
| 40 | +* You may program procedurally if you like (but it will still be |
| 41 | + object-oriented behind the scenes). |
| 42 | +* Most of the operators are the same (including the compound assignment |
| 43 | + and also bitwise operators). Though, Ruby doesn’t have `++` or `--`. |
| 44 | +* You’ve got `__FILE__` and `__LINE__`. |
| 45 | +* You can also have constants, though there’s no special `const` |
| 46 | + keyword. Const-ness is enforced by a naming convention instead— names |
| 47 | + starting with a capital letter are for constants. |
| 48 | +* Strings go in double-quotes. |
| 49 | +* Strings are mutable. |
| 50 | +* Just like man pages, you can read most docs in your terminal |
| 51 | + window—though using the `ri` command. |
| 52 | +* You’ve got the same sort of command-line debugger available. |
| 53 | + |
| 54 | +### Similarities with C++ |
| 55 | + |
| 56 | + As with C++, in Ruby,... * You’ve got mostly the same operators (even `::`). `<<` is often used |
| 57 | + for appending elements to a list. One note though: with Ruby you never |
| 58 | + use `->`—it’s always just `.`. |
| 59 | +* `public`, `private`, and `protected` do similar jobs. |
| 60 | +* Inheritance syntax is still only one character, but it’s `<` instead |
| 61 | + of `:`. |
| 62 | +* You may put your code into “modules”, similar to how `namespace` in |
| 63 | + C++ is used. |
| 64 | +* Exceptions work in a similar manner, though the keyword names have |
| 65 | + been changed to protect the innocent. |
| 66 | + |
| 67 | +### Differences from C |
| 68 | + |
| 69 | +Unlike C, in Ruby,... |
| 70 | + |
| 71 | +* Objects are strongly typed (and variable names themselves have no type |
| 72 | + at all). |
| 73 | +* There’s no macros or preprocessor. No casts. No pointers (nor pointer |
| 74 | + arithmetic). No typedefs, sizeof, nor enums. |
| 75 | +* There are no header files. You just define your functions (usually |
| 76 | + referred to as “methods”) and classes in the main source code files. |
| 77 | +* There’s no <tt>#define</tt>. Just use constants instead. |
| 78 | +* As of Ruby 1.8, code is interpreted at run-time rather than compiled |
| 79 | + to any sort of machine- or byte-code. |
| 80 | +* All variables live on the heap. Further, you don’t need to free them |
| 81 | + yourself—the garbage collector takes care of that. |
| 82 | +* Arguments to methods (i.e. functions) are passed by reference, not by |
| 83 | + value. |
| 84 | +* It’s `require 'foo'` instead of `#include <foo>` or `#include "foo"`. |
| 85 | +* You cannot drop down to assembly. |
| 86 | +* There’s no semicolon’s ending lines. |
| 87 | +* You go without parentheses for `if` and `while` condition expressions. |
| 88 | +* Parentheses for method (i.e. function) calls are often optional. |
| 89 | +* You don’t usually use braces—just end multi-line constructs (like |
| 90 | + `while` loops) with an `end` keyword. |
| 91 | +* The `do` keyword is for so-called “blocks”. There’s no “do statement” |
| 92 | + like in C. |
| 93 | +* The term “block” means something different. It’s for a block of code |
| 94 | + that you associate with a method call so the method body can call out |
| 95 | + to the block while it executes. |
| 96 | +* There are no variable declarations. You just assign to new names |
| 97 | + on-the-fly when you need them. |
| 98 | +* When tested for truth, only `false` and `nil` evaluate to a false |
| 99 | + value. Everything else is true (including `0`, `0.0`, and `"0"`). |
| 100 | +* There is no `char`—they are just 1-letter strings. |
| 101 | +* Strings don’t end with a null byte. |
| 102 | +* Array literals go in brackets instead of braces. |
| 103 | +* Arrays just automatically get bigger when you stuff more elements into |
| 104 | + them. |
| 105 | +* If you add two arrays, you get back a new and bigger array (of course, |
| 106 | + allocated on the heap) instead of doing pointer arithmetic. |
| 107 | +* More often than not, everything is an expression (that is, things like |
| 108 | + `while` statements actually evaluate to an rvalue). |
| 109 | + |
| 110 | +### Differences from C++ |
| 111 | + |
| 112 | +Unlike C++, in Ruby,... |
| 113 | + |
| 114 | +* There’s no explicit references. That is, in Ruby, every variable is |
| 115 | + just an automatically dereferenced name for some object. |
| 116 | +* Objects are strongly but *dynamically* typed. The runtime discovers |
| 117 | + *at runtime* if that method call actually works. |
| 118 | +* The “constructor” is called `initialize` instead of the class name. |
| 119 | +* All methods are always virtual. |
| 120 | +* “Class” (static) variable names always begin with <tt>@@</tt> (as in |
| 121 | + <tt>@@total\_widgets</tt>). |
| 122 | +* You don’t directly access member variables—all access to public member |
| 123 | + variables (known in Ruby as attributes) is via methods. |
| 124 | +* It’s `self` instead of `this`. |
| 125 | +* Some methods end in a ’?’ or a ’!’. It’s actually part of the method |
| 126 | + name. |
| 127 | +* There’s no multiple inheritance per se. Though Ruby has “mixins” (i.e. |
| 128 | + you can “inherit” all instance methods of a module). |
| 129 | +* There are some enforced case-conventions (ex. class names start with a |
| 130 | + capital letter, variables start with a lowercase letter). |
| 131 | +* Parentheses for method calls are usually optional. |
| 132 | +* You can re-open a class anytime and add more methods. |
| 133 | +* There’s no need of C++ templates (since you can assign any kind of |
| 134 | + object to a given variable, and types get figured out at runtime |
| 135 | + anyway). No casting either. |
| 136 | +* Iteration is done a bit differently. In Ruby, you don’t use a separate |
| 137 | + iterator object (like `vector<T>::const_iterator iter`) but instead |
| 138 | + your objects may mixin the `Enumerator` module and just make a method |
| 139 | + call like `my_obj.each`. |
| 140 | +* There’s only two container types: `Array` and `Hash`. |
| 141 | +* There’s no type conversions. With Ruby though, you’ll probably find |
| 142 | + that they aren’t necessary. |
| 143 | +* Multithreading is built-in, but as of Ruby 1.8 they are “green |
| 144 | + threads” (implemented only within the interpreter) as opposed to |
| 145 | + native threads. |
| 146 | +* A unit testing lib comes standard with Ruby. |
0 commit comments