Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Introduction to Ruby
Sebastian Fischer
Part I
•Data
Numbers, Strings, Ranges, Arrays/Hashes
•Control
Branching, Loops, Iterators
Numbers
>>
=>
>>
=>
>>
=>
42
42
-17
-17
1.23
1.23
>>
=>
>>
=>
>>
=>
4.56e7
45600000.0
2.34e-4
0.000234
2.34>0
true
>>
=>
>>
=>
>>
=>
17e-1.round
2
17/4
4
17./ 4
4
Strings
>>
=>
>>
=>
>>
=>
>>
=>
>>
=>
hello = "hello"
"hello"
world = "world"
"world"
hello = "#{hello} #{world}!"
"hello world!"
hello.chop!
"hello world"
hello
"hello world"
Escape
>>
=>
>>
=>
>>
=>
>>
=>
"hello\nworld!"
"hello\nworld!"
'hello\nworld!'
"hello\\nworld!"
"hello#{17+4}world!"
"hello21world!"
'hello#{17+4}world!'
"hello\#{17+4}world!"
Regular Expressions
>>
=>
>>
=>
>>
=>
>>
=>
>>
=>
hello =~ /\s\w+/
5
hello[5,6]
" world"
hello[5..10]
" world"
hello.gsub!(/\s\w+/,'\&!')
"hello world!"
hello
"hello world!"
Ranges
>>
=>
>>
=>
>>
=>
1..3
1..3
(1..3).first
1
(1..3).last
3
>>
=>
>>
=>
>>
=>
(1..3).member? 3
true
(1..3).member? 4
false
(1..3).entries
[1, 2, 3]
Arrays
>>
=>
>>
=>
>>
=>
>>
=>
>>
=>
a = [1,true,"huh?"]
[1, true, "huh?"]
a[2]
"huh?"
a.length
3
a + [42]
[1, true, "huh?", 42]
a * 2
[1, true, "huh?", 1, true, "huh?"]
Arrays
>>
=>
>>
=>
>>
=>
>>
=>
(a*2)[2..4]
["huh?", 1, true]
(a*2)[2,3]
["huh?", 1, true]
a[-1]
"huh?"
a[-2]
true
Hashes
>>
=>
>>
=>
>>
=>
>>
=>
>>
=>
>>
=>
h = { 1 => true, "huh?" => 2.34 }
{1=>true, "huh?"=>2.34}
h[1]
true
h["huh?"]
2.34
h[true]
nil
h[true] = 42
42
h
{true=>42, 1=>true, "huh?"=>2.34}
Symbols
>>
=>
>>
=>
>>
=>
>>
=>
:foo
:foo
:foo.to_i
14609
:foo.id2name
"foo"
"foo".to_sym
:foo
Data
•Numbers
•Strings, Regular Expressions
•Ranges
•Arrays
•Hashes
If, Unless
>>
=>
>>
=>
>>
=>
>>
=>
if 3>0 then 42 else 87 end
42
42 if 3>0
42
unless 3>0 then 42 else 87 end
87
87 unless 3>0
nil
Case
>>
>>
>>
>>
>>
>>
=>
case i
when 1, 2..5
"one to five"
when 6..10
"six to ten"
end
"six to ten"
>>
=>
>>
=>
>>
>>
>>
>>
>>
>>
=>
case "abcdef"
when "abc" ,"def"
"abc or def"
when /def/
"includes def"
end
"includes def"
(6..10) === 8
true
/def/ === "abcdef"
true
While
>>
=>
>>
>>
>>
>>
=>
fac5 = 1; n = 1
1
while n <= 5
fac5 = fac5 * n
n = n+1
end; fac5
120
While
while (<condition>) {
label_redo:
<body>
label_next:
}
label_break:
Until
>>
=>
>>
>>
>>
>>
=>
fac5 = 1; n = 1
1
until n > 5
fac5 = fac5 * n
n = n+1
end; fac5
120
For/in
>>
>>
>>
>>
=>
fac5 = 1;
for n in 1..5
fac5 = fac5 * n
end; fac5
120
Iterators
>>
=>
>>
=>
>>
=>
fac5 = 1
1
(1..5).each { |n| fac5 = fac5 * n }
1..5
fac5
120
Iterators
>> "hello".each_byte { |b| puts b }
104
101
108
108
111
=> "hello"
>> "hello\nworld!".each { |l| puts l }
hello
world!
=> "hello\nworld!"
Iterators
>> (1..3).each{ |n| print n }
123=> 1..3
>> [1,2,3].each{ |n| print n }
123=> [1, 2, 3]
>> h.each{ |k,v| puts "#{k} => #{v}" }
true => 42
1 => true
=> {true=>42, 1=>true}
Iterators
>> 3.times { puts "hello" }
hello
hello
hello
=> 3
>> 1.upto(3) do |n|
?>
puts n
>> end
1
2
3
=> 1
Control
•if, unless
•case
•while, until, for/in
•Iterators
Part II
•Classes and Objects
Inheritance, Methods, Access Control
•Accessor Methods
•Modules
Classes
>>
>>
>>
>>
>>
>>
=>
class Person
def initialize name
@name = name
end
end
me = Person.new "Sebastian"
#<Person:0x362180 @name="Sebastian">
Classes
class Man < Person
def initialize name
super name
@gender = :male
end
end
class Woman < Person
def initialize name
super name
@gender = :female
end
end
Objects
>> me = Man.new "Sebastian"
=> #<Man:0x356588
@gender=:male,
@name="Sebastian">
>> me.@name
SyntaxError: compile error
>> me.name
NoMethodError:
undefined method `name' for
#<Man:0x356588
@gender=:male,
@name="Sebastian">
Accessor Methods
class Person
def name
@name
end
def name=(n)
@name = n
end
end
class Person
attr_accessor :name
end
Accessor Methods
>>
=>
>>
=>
>>
=>
me.name
"Sebastian"
me.name = "Horst"
"Horst"
me
#<Man:0x356588
@gender=:male,
@name="Horst">
Modules
module WithGender
attr_reader :gender
end
class Man
include WithGender
end
class Woman
include WithGender
end
Reader Methods
>> me.gender
=> :male
>> me.gender = :female
NoMethodError:
undefined method `gender=' for
#<Man:0x356588
@gender=:male,
@name="Horst">
Singleton Methods
>>
>>
>>
=>
>>
=>
>>
=>
def me.gender=(g)
@gender = g
end
nil
me.gender = :female
:female
me
#<Man:0x356588
@gender=:female,
@name="Horst">
Modules
module Student
@@nr = 0
attr_reader :nr
def next_nr
@@nr += 1
end
private :next_nr
end
Mixin
class MaleStudent < Man
include Student
def initialize name
super name
@nr = next_nr
end
end
class FemaleStudent < Woman
include Student
...
end
Accessor Methods
>> axel = MaleStudent.new "Axel"
=> #<MaleStudent:0x3631d4
@name="Axel", @nr=1
@gender=:male>
>> rita = FemaleStudent.new "Rita"
=> #<FemaleStudent:0x361294
@name="Rita", @nr=2,
@gender=:female>
>> axel.gender
=> :male
>> rita.nr
=> 2
Extending Classes
>>
>>
>>
>>
>>
>>
=>
>>
=>
class Integer
def fact
return 1 if self==0
self * (self-1).fact
end
end
nil
5.fact
120
Class Hierarchies
>>
=>
>>
=>
>>
=>
>>
=>
>>
=>
5.class
Fixnum
Fixnum.superclass
Integer
Integer.superclass
Numeric
Numeric.superclass
Object
Object.superclass
nil
Classes are Objects
>>
=>
>>
=>
>>
=>
>>
=>
>>
=>
Integer.class
Class
Class.class
Class
Class.superclass
Module
Module.class
Class
Module.superclass
Object
“Global” Functions
>>
>>
>>
=>
>>
=>
>>
=>
>>
=>
def square x
x*x
end
nil
self.methods.select {|m| m =~ /sq/ }
["square"]
42.methods.select {|m| m =~ /sq/ }
["square"]
"".square 7
49
Scope
>> ["a","b","c"].each {|str| print str}
abc=> ["a", "b", "c"]
>> str
NameError:
undefined local variable or method
`str' for main:Object
>> str = "z"
=> "z"
>> ["a","b","c"].each {|str| print str}
abc=> ["a", "b", "c"]
>> str
=> "c"
Variables
•Constants
uppercase: Math::PI
•Global Variables
dollar sign: $PROGRAM_NAME
Constants
>>
=>
>>
=>
>>
=>
Object.constants
["IO", "Student", ...]
Student.constants
[]
WithGender.constants
[]
Prettier Objects
module Student
def inspect
str = "Student: #{nr}"
str += ", Name: #{name}" \
if respond_to? :name
str += ", Gender: #{gender}" \
if respond_to? :gender
str
end
end
Prettier Objects
>> axel
=> Student: 1, Name: Axel, Gender: male
>> puts axel
#<MaleStudent:0x365470>
=> nil
Prettier Objects
>> class Person
>>
def to_s; inspect end
>> end
>> puts axel
Student: 1, Name: Axel, Gender: male
=> nil
Exceptions
class Person
def name=(n)
raise "name must not be empty!" \
if n.empty?
@name = n
end
end
>> me.name = ""
RuntimeError: name must not be empty!
Exceptions
>> begin
?> me.name = ""
>> puts 'name was set to ""'
>> rescue
>> puts "could not set name"
>> ensure
?> puts "finished"
>> end
could not set name
finished
=> nil
Useful Stuff
>> 5.f
5.floor
5.freeze
5.frozen?
>> 5.f
>> 5.methods
=> ["%", "inspect", ...]
5.fact
Useful Stuff
$ ri Array#each
-----------------------------Array#each
array.each {|item| block } -> array
--------------------------------------Calls _block_ once for each element in
_self_, passing that element as a
parameter.
...
Ruby will teach you to
express your ideas through
a computer. You will be
writing stories for a
machine.
http://poignantguide.net/ruby/
Part III
•Object#send
•Method#call
•Kernel#eval
Object#send
>>
=>
>>
=>
>>
=>
"hello world".send :length
11
"hello world".send "length"
11
"hello".send :<<, " world"
"hello world"
Method#call
>>
=>
>>
=>
>>
=>
"hello world".method(:length).call
11
app = "hello".method :<<
#<Method: String#<<>
app.call(" world")
"hello world"
Kernel#eval
>>
=>
>>
=>
>>
eval '"hello world".length'
11
eval '"hello" << " world"'
"hello world"
eval 'system "rm *"'
Module#class_eval
class Module
def my_attr_reader sym
class_eval "def #{sym}()"
<< " @#{sym} end"
end
def my_attr_writer sym
class_eval "def #{sym}=(v)"
<< " @#{sym}=v end"
end
end
Attribute Accessors
class Klass
my_attr_reader :a
my_attr_reader :b
my_attr_writer :b
def initialize() @a=42 end
end
Attribute Accessors
>>
=>
>>
=>
>>
=>
>>
=>
klass = Klass.new
#<Klass:0x353784 @a=42>
klass.a
42
klass.b = 17
17
klass.b
17
http://www.ruby-doc.org/docs/ProgrammingRuby/