Learning Ruby
- Foreword
- Why and About ruby
- Datatypes
- Duct Typing
- Hashes and Arrays
- Strings and qu(ai)rks
- Re(ge)x(p)
- How to class?!?!
- Monkeypatching!
- Dynamic Reflections and stuff
Foreword
This document assumes you know some other languages already, preferrably Java, PHP or something with a similiar C style syntax.
Why and about ruby
In ruby, _everything_ is a class/object, similiar to javascript. It also allows patching code on runtime and has decent reflection stuff and all you need and ever want.
Datatypes
Everything is an object in ruby, but you should know that there is a special type of string, the "SYMBOL".
A Symbol is a const string, and the notation is like :mysym
Most objects support the following methods to convert between common types:
'foo'.to_i # => Exception?
'5'.to_i # => 5
5.to_s # => "5"
5.to_f # = 5.0
'foo'.to_sym # => :foo
:foo.to_s # => "foo"
A short syntax
In ruby you can write very short and elegant code. Like in perl it might be hard to read then for beginners, or even for yourself.
# Prepended if
foo = bar if bar != nil
# unless; the opposite of if
foo = bar unless bar.nil?
# No need for return
def default_username
"Peter"
end
# Semicolon only needed for multiple statements in a single line
def default_username; "Peter"; end
# No need for parantheses
class Peter
def i_could_be_an_attribute; 4; end
end
Peter.new.i_could_be_an_attribute # => 4
Duct Typing
Hashes and Arrays
Ruby is like Javascript here.
myarray = [1,2,3]
myhash = {foo:'bar', blub:[1,2,3], :foo2 => "bar2"}
Just note that foo: 'bar' is the same as :foo => 'bar'
Strings and qu(ai)rks
Similar to PHP, you can define Strings as literal or with interpreter support.
s1 = '#{2.minutes}' # => "#{2.minutes}":String
s2 = "#{2.minutes}" # => "120":String
In ruby you can have extra fancyness: %q/%Q allows both quotes without escaping.
s1 = %q{'"*"'"}.length # => 5
Re(ge)x(p)
Here ruby is a bit like Perl.
TODO: explain =~
matches = /^[a-z][a-z_0-9]{15}$/i.match(s) # => nil||Array
Regexp.new("^[a-z][a-z_0-9]{#{len}}$", true).match(s) # => nil||Array
How to class in ruby?!?!
Ruby is quite different from C++, Java and PHP when it comes to class definitions.
Instance variables are donated as @myinstancevar. They are only visible within the class, no inheritance.
To make an instance variable visible you have to create a public method which returns it, or use reflection: myobj.instance_variable_get(:@myinstancevar)
Code Example:
class MyClass
@i_am_static_because_i_am_not_inside_a_function_o_o = 3
def initialize(arg=nil)
# I am the constructor, called on MyClass.new
@a_normal_instance_var = 5
end
def get_normal
@a_normal_instance_var
end
def a_normal_instance_var=(value)
# Ruby methods can contain =(setter), ?(beauty), and !(assign to self, call_exception, force, whatever you feel like an exclamation could mean)
@a_normal_instance_var = value
end
def [](index)
"You have sent me [#{index}]"
end
def self.i_am_a_static_method
@i_am_static_because_i_am_not_inside_a_function_o_o = 8
end
private
def i_am_a_private_method
end
end
Call static methods like this:
MyClass.i_am_a_static_method
MyClass.new(5).class.i_am_a_static_method
Monkeypatching!
Now my favorite part about ruby... patching existing code :)
It is simple as that; every definition you write extends the existing defintion:
class MyClass
def foo
"Hello"
end
end
class MyClass
def bar
"Now MyClass has foo and bar methods \o/"
end
end
class MyClass
def foo
"Hello World, i overwrote you!"
end
end
But beware; Monkeypatching is not a good coding practice and can easily lead to problems!
Dynamic Reflections and stuff
You probably want to use dynamic methods and attributes.
Simply use "send" to call methods dynamically: myobj.send('thefunc', arg1, arg2)
Use myobj.instance_variable_get, myobj.instance_variable_set, myobj.instance_variable_defined? to handle attributes.