A QUICK INTRODUCTION TO RUBY by Renaud Waldura December 12th 2000 Target audience: programmers already familiar with either Perl or Java. Ideally, both. :) 1. BASICS Statement separator is semicolon or newline. Single-line comments start with "#". Multi-line comments are enclosed between "=begin" and "=end". Here documents OK. Double-quoted strings, single-quoted strings. All backslash-combinations are there (\n etc.) Evaluation inside a double-quoted string is done with #{expr}, e.g. var = 1 string = "one#{var + 1}many" 2. LITTERALS & VARIABLES Variables are always undeclared and untyped. local_variable @instance_variable @@class_variable $global_variable Constant or CONSTANT self, nil, true, false array = [ 'a'..'z', 'A'..'Z' ] hash = { 'a' => 1, 'b' => 2 } regexp = /^[rR]uby/ Also Perl-like one-character global variables, e.g. $$, $@, etc. Assignment always creates a new reference to the object, not a copy, except for simple types (integers, floats, chars, but not strings). Symbols are accessed with ":symbol_name"; often used with eval(). Operators are C-like for the most part. Most are just method calls and hence overloadable. Also funky quoting operators %q(), %x(), %r(), etc -- inspired from Perl again. 3. CLASSES AND METHODS class Class_name < Super_class def method_name(arg1, arg2) method_body end end def function_name(arg1, arg2 = default_value) function_body end Accessors are defined with special keywords: class MyClass attr_read :read_only_attribute attr_write :write_only_attribute attr_accessor :read_write_attribute end Access control is similar to C++: private :method_name protected :method_name public :method_name Destructive methods (methods altering the object they're called on) end in "!"; e.g. String.concat!(). Everything is a method (see below). All arguments are always passed by value; but since most of them are references, it ends up being passing by reference anyway. Varargs specified with starred parameter: def main(argc, *argv) argv is an array for arguments. Star is also used to do the opposite, ie. expand an array before a method call. E.g.: a = [ 1..3 ] foo(*a) <=> foo(1, 2, 3) Call Class_name.ancestors() to know which method will be called for a given class. Operator redefinition: +, -, * are really method names and can be redefined, but not "=" which is used in accessors. No ++, no --, but += and friends are OK. No method overloading., e.g. def f(a) def f(a, b) is NOT okay. 4. MODULES Modules are used for namespace control. module Module_name # module body end Modules can be included with "include Module_name", giving unqualified access to their content. Or use the scope operator "::". Modules are comparable to Java's interfaces, and used in the same way to emulate multiple inheritance (the module is included in the class definition; it's a mixin). 5. SINGLETONS Similar to class methods. Singleton methods can be used to redefine an instance's (or a class's) method; e.g. i = Class.new def i.method # new code end Singleton methods are used in place of function pointers. Top-level functions are actually singletons inserted into the Object class. Note from the Ruby FAQ: Ruby is a pure OO language that can masquerade as a procedural one. It has no functions, only method calls. In a Ruby method the receiver, also called self, is a hidden argument like ``this'' in C++. A ``def'' statement outside of a class definition [...] is actually a method call in Ruby. These ersatz functions become private methods of class Object, the root of the Ruby class hierarchy. Procedural programming is neatly solved from the other direction - everything is an object. 6. PROCEDURE OBJECTS A.k.a closures. Created with the proc operator; e.g.: p = proc { print "abc\n" } p.call They can be anonymous. They can be passed arguments: p = proc { |a, b| print a + b, "\n" } p.call(1, 2) When passed a block as argument, call "yield" to transfer control to that block. With procedure object, use p.call() as shown above. The "&" operator is used to convert between a proc object and a block: &proc => block. 7. ITERATORS Maybe one of Ruby's best features. Who isn't sick to death of manually iterating over some data structure? I am. Quick example that says it all: data = [1, 2, 3] data.each { |i| print i, "\n" } Use "yield" inside your own iterator to transfer control to the block the iterator is passed as argument. E.g.: ... 8. EXCEPTIONS begin # code raising exceptions, e.g. raise "my exception" rescue # deal with exception found in $! retry # let's try again ensure # equivalent to Java's finally, ie. do this block # whatever happens end 9. CAVEAT In Ruby, only "nil" and "false" really mean false; everything else, including 0 (zero) and "" (the empty string) evaluate to true. 10. ADDITIONAL RESOURCES The Ruby FAQ at http://www.rubycentral.com/faq/ The Ruby Reference Manual ??