Skip to content

Lecture 02

Marek Jelen edited this page Oct 4, 2011 · 21 revisions

Basics

Responsibility

You should always have on mind that with great power comes great responsibility.

Separating code into files

In Ruby code can be separated into files. To load code from file use require

require "somefile.extension"

File with extension [rb, so, o, dll, bundle, jar] can be addressed without the extension. Having a file called somefile.rb these two are equivalent

require "somefile"
require "somefile.rb"

The file, if it is not absolute path, will be looked from paths contained in $: variable. $: is Array and user is free to add it's own paths or delete others. Required files are tracked in variable $". If a path is already in $", than it will not be required again. $" is also Array and user is free to modify it.

Execution

Every line in Ruby is an expression. That means that every line of Ruby is just executable code. There is a top level context that is just simple instance of Object (required files are executed in this context).

For example:

class A
  puts "Hello world"
end

will print "Hello world" and define new class A. We can put executable code anywhere in Ruby. And everything is just an execution.

Return statements

Ruby behaves in a way that every code is executable - is an expression. By definition an expression should have some return value - the result of it's execution. Let's take a look at this example

class A
end

What is the result of such an expression? You might say "we defined class A". But it is not. The fact we defined a class is only an effect of the expression but not a result ... result is a value returned from the expression itself.

var = nil
puts var.inspect
# => nil

var = class A
end

puts var.inspect
# => nil

The value have not changed .... there is no resulting value. Wrong again. The resulting value was simply nil, the same value as in the variable, but it was returned.

var = nil
puts var.inspect
# => nil

var = class A
  self
end

puts var.inspect
# => A

In this example we get a return value. As we can see, it is a class A. How is that possible? The last line of a method is return value. Do you remember? Basically we can generalize to last line of an expression is it's return value.

Context

As said before, everything in executed in some context. This context is know as current object and is always represented by self.

self.class
# => Object

class B
  self
end
# => Class

class A
  def call
    self
  end
end

A.new.call
# => #<A:some number>

Class

Open classes

Unlike most languages, Ruby classes are open for modifications. This way programmer can modify behavior of classes defined by frameworks or Ruby itself. This technique is called Monkey patching.

class Clazz
  def call
    "A"
  end
end

class Clazz
  def call
    "B"
  end
end

Clazz.new.call()
# => "B" 

What is a class?

People unfamiliar with Ruby might ask, why is the precedent example valid and the answer is simple:

classes are objects

everything in Ruby is an object ... even a class. Don't you believe me? Try this example:

class A
  def self.call
    "called"
  end
end

class B
end

def B.call
  "called"
end

C = Class.new

class C
  def self.call
    "called"
  end
end

D = Class.new

def D.call
  "called"
end

A.call # => "called"
B.call # => "called"
C.call # => "called"
D.call # => "called"

In the example we defined 4 classes, with class method call that return string "called" all those 4 techniques are equivalent and you can mix them freely.

Inheritance

One class can inherit from another. Ruby has only single-class inheritance - you can not inherit from multiple classes.

class A
  def call
    "called"
  end
end

class B < A
end

C = Class.new(B)

B.new.call
# => "called"
C.new.call
# => "called"

Mixins

When a class needs to inherit from multiple classes, Ruby allows as to mix in multiple Modules. Methods of these modules are then available to the class.

module Methods
  def call
    "called"
  end
end

class A
  include Methods
end

A.new.call
# => "called"

Objects

To create an object of some class it is used the method new of that class.

class Dog
end

dog = Dog.new

http://blog.madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html

Clone this wiki locally