1. What is Ruby?
- A general purpose programming language
- Purely object orientated, as in Smalltalk "every is an object"
- Interpreted
- Dynamic but strong typed (stronger than C, no typecasts, no pointers)
1.1. Some features
Documentation/Library
I think the most important part of a language is it's library. A syntax of a language can be learned quickly in some hours, the library not, and it's the library you are working with the most time.
What I mostly disliked at Perl and Python was, that it is much harder to find a method/function you are searching for. Both have build-in types and use build-in functions. It is very hard to find them in the documentation. For example I spend half an hour (as a guy having written Pyhton programs three year ago) to find a list of methods a Python list-type provides, but I didn't found that neither in the Library Reference nor in the Global Module Index.
Another point is that looking at the Global Module Index shows you around 250 different modules coming with Python (are they really included?). Ruby instead comes perhaps with only 30 modules/classes.
There should always be a differentiaion between the standard library as general purpose library (this should also be platform independent) used in most programs and the libraries for special purposes (e.g. graphics, images, sound...).
- Now if you are a bit familiar with Ruby, but often forget a method name, use "irb -r irb/completion" and you can use the TAB key to show all methods of the current object and complete it. Great work !
- For a description of a method/class use "ri method/class". No more searching for a description of a method/class! Thanks Dave & Andy !
- Ruby has very powerful standard libraries, e.g. Array and Hash are very powerful while easy to use. You can do with Ruby's Array class everything for which you would need n classes/modules in Python.
Clean object model
- very clean object model; there are (almost) no exceptions to it
- Instance variables (attributes) are (like in Eiffel or Smalltalk but unlike Python) not accessible from outside the class/object. You have to define methods for that (attr_reader, attr_writer or attr_accessor will do the job for you).
- Single inheritance (not neccessary a feature); MI possible through Mixin
- Operators are methods => can be redefined; [] and []= can be redefined
- Ranges a..b are instances of class Range; this is just syntactical sugar
- Regular expressions /.../ are instances of class Regexp; this is just syntactical sugar
- Meta classes (classes are first-class objects)
- classes in Ruby are itself objects
- clean object creation by calling methods (no constructors). For example String.new creates a new instance of class String where new is a normal method defined in the class of object String.
Syntax
- There is some syntactical sugar, e.g. Regexps as in Perl or Ranges. This makes Ruby more usable for scripts, but also lets look your code nicer. But less build-in semantics (as in Perl; Python?), almost everything is a method call and you can overwrite the method.
- Eiffel-like syntax, i.e. no blocks needed as in Pascal or C/C++.
- Ruby distinguishes the different types of variables (local, global, instance, class and constants) by different syntax for them. This saves you from typing "global" (Python) or "my", "local" (Perl) while it makes it obvious which type of variables you're currently using without looking at the declaration (first usage).
- readable and informative naming of methods, e.g. empty? (returns true or false), tr! (destructive method: modifies the object instead of operating on a copy) and value= (setter method: a.value = "hallo" looks like variable assignment in Python but is in reallity a method call to value=)
- "clean" syntax; people coming from other languages will easily adapt this one
- no indentation as in Python (personal preference); easier to generate code automatically
Lightweight Threads
- available on every platform, even on singletask operating systems like DOS or on PDAs
- threads are a part of the language not a library
- this affects the way of solving problems; you use threads where you wouldn't have used native threads, e.g. flattening a recursion etc..
- no problem to create 1000 or more threads
- uses much less ressources than native threads
- automatic deadlock recognition by the interpreter
- BUT: not native => C extensions may block the whole interpreter => use processes
Build-in Bignums
- arbitrary precise integers are build into Ruby (Pyhton has this too, e.g: 12312312312312L)
- automatic conversion from Fixums (31 bit integer) to Bignums.
- you don't have to care about the size of the integer
Iterators and Code blocks
- used very often
- makes code more readable, less errors
Some usages of iterators:
a = [1,2,3,4] a.each {|i| p i} # simple iterator a.collect {|i| i*i} # => [1,4,9,16] a.select {|i| i > 2} # => [3,4] a.inject(0) {|i, j| i+j} # => sum of all elements File.readlines("/etc/hosts").grep( /^A/ ).to_s
You get the methods like collect, select etc. for free; just define method each in your object and mixin module Enumerable.
File.open( "/etc/hosts" ) do | file | .... end DBI.connect(...) do | dbh | sql = "SELECT * FROM X WHERE a = ? and b = ?" dbh.prepare( sql ) do | sth | sth.execute( ... ) sth.select {|row| p row["a"] == "test" } end end
The file or database (or prepared statement) is automatically closed at the end of the block.
Garbage Collector
- real mark and sweep GC
- no reference counting as in Perl or Python (Python has mark & sweep GC since 2.x too, but not for extensions)
- Ruby 1.8: generational GC => gains a lot of performance
Powerful and easy to use C interface
- very easy to write new C extensions or embed Ruby in other applications