LearningRuby

About this page

The purpose of this page is to keep my notes about my dabblings into the Ruby progamming language. I doubt very much that this page is of any use to somebody besides myself. If you are not myself, you probably better look at one of the tutorials listed in the "References" section.


Why Ruby?

I started to get acquainted with the language to prepare myself for a job interview with a prospective future employer. Actually I have been interested in Ruby for a long time, but at some point in the past I had to decide whether to go down the Python or the Ruby road. At that time I decided for Python, mostly because I intended to become involved with the ISFDB project.


References

Introduction material:

Ruby From Other Languages 
http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/


Tutorials:

Ruby in Twenty Minutes 
http://www.ruby-lang.org/en/documentation/quickstart/
Ruby Essentials 
http://www.techotopia.com/index.php/Ruby_Essentials
Learning Ruby 
http://rubylearning.com/
Ruby & Ruby on Rails tutorials 
http://www.meshplex.org/wiki/Ruby/Ruby_on_Rails_programming_tutorials

Manuals:

Programming Ruby 
http://www.ruby-doc.org/docs/ProgrammingRuby/


Glossary

RoR 
Ruby on Rails


Open questions

  • Indentation conventions?


Coding Ruby

First impressions

  • Extensions can be written in C, much the same as in Python
  • Const'ness is enforced by naming things with capital letters, not with a special keyword
  • No preprocessor
  • There is a garbage collector
  • No formal variable declarations
  • Everything is an object, there are no primitive types
  • No char type, instead single characters are simply strings of length 1
  • No pointers, no explicit references - everything is simply a reference to an object
  • No virtual statement
  • No multiple inheritance - we are saved!
  • Indentation is not relevant to the code structure
  • Class member variables are private, full stop! Access is via methods only.
  • Access to methods is regulated with public, protected and private (same/similar as C++ and Java, but unlike Python)
  • == corresponds to equals() in Java, and equal?() corresponds to ==


Interactive shell

Ruby's interactive shell can be fired up like this:

irb

Note that irb has its own version that is different from the Ruby interpreter itself. For instance, on my Mac OS X 10.5 machine:

tharbad:~ --> irb --version
irb 0.9.5(05/04/13)
tharbad:~ --> ruby --version
ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]


Executing a Ruby script

Basics

The script must have the executable bit set and contain a shebang at the top.

tharbad:~/ruby --> ls -l helloworld.rb
-rwxr-xr-x  1 patrick  staff  41 18 Jan 14:14 helloworld.rb
tharbad:~/ruby --> cat helloworld.rb
#!/usr/bin/env ruby

puts("hello world")


Distinguishing between main program and library code

If you want to determine whether your script runs as the main program, or is executed as "library code", i.e. as part of some other program, then the following code fragment is useful:

if __FILE__ == $0
  [...]
end


Command line arguments

TODO


Variables

Variables are just references to objects. Variables do not need to be declared, they can be created just like that:

foo = "bar"


nil

Ruby uses the value nil to indicate that something has "no value". For instance:

foo = nil
if foo.nil?   # This is a specially named method
  [...]
end


Flow control

if

if foo.nil?
  puts "it's got no value"
elsif foo == 42
  puts "it is forty-two"
else
  puts "it is something else"
end


each

If an object responds to the each message it is something that can be iterated over, much like a traditional for...each loop:

foo = ["foo", "bar", "42"]
foo.each do |element|
  puts("element is #{element}")
end

# Query an unknown
if foo.responds_to?("each")
  foo.each do |element|
    puts("element is #{element}")
  end
end


while

TODO


Functions

Use def to start a function definition:

def f(foo = "foo", bar = "bar")
  puts foo + " " + bar
end

# Invoke the function:
f("hello", "world")
f()
f

Notes:

  • There's no need to define a return value: Everything always has a return value
  • If the function doesn't return an explicit value, it implicitly is nil


Strings

Strings are normal objects, and they are mutable.

foo = "bar"

Inserting something into a string works as in the following example. The object referenced by the variable is turned into a string and then inserted into the enclosing string. Optionally, the referenced object can be sent a message first and the result is then inserted.

foo = "world"
puts("hello #{foo}")
puts("Hello #{foo.capitalize()}")


Object orientation

Classes

Define a class like this:

class MyClass
  # Generates a getter "name()" and a setter "name=()"
  attr_accessor :name

  # The special name "initialize" is the class' constructor
  def initialize(name = "foo")
    # Prefixing a variable with "@" refers to an instance variable
    @name = name
  end

  # A regular instance method; public since we didn't specify anything else
  def printIt()
    puts(@name)
  end
end

Instantiate the class and access its methods and attributes:

obj = MyClass.new()   # This looks really great (although unaccustomed): new is not a keyword, it's just a message!
obj = MyClass.new("bar")
obj.printIt()
puts(obj.name)     # Invoke the getter
puts(obj.name())
obj.name="foo"     # Invoke the setter
obj.name=("foo")


Introspection

class MyClass
  [...]
end
obj = MyClass.new()

obj.class()                        # Returns the object's class object
MyClass.class()                    # Classes are also objects themselves; the class object here is "Class"
MyClass.instance_methods()         # Returns an array; includes instance methods of superclasses
MyClass.instance_methods(false)    # Don't inspect superclasses
MyClass.instance_variables()       # Returns an array
obj.respond_to?("foo")             # Does the object respond to this message?
obj.is_a?(MyClass)                 # Requires a class object
MyClass.is_a?(Class)               # "Class" is the type that all class objects have
Class.is_a?(Class)                 # Yes, the class object "Class" (first) is an instance of the class "Class" (second)


Eclipse and Ruby

RadRails

RadRails can be used either as a plugin within the accustomed Eclipse IDE environment, or it can be installed as a standalone IDE. The update site for the plugin is

http://download.aptana.com/tools/radrails/plugin/install/radrails-bundle

and the standalone installer can be downloaded from this location

http://www.radrails.org/download/


Workspace configuration

TODO


Project configuration

TODO