Upload
vladimir-bystrov
View
4.161
Download
2
Tags:
Embed Size (px)
DESCRIPTION
Ruby basics, OOP, metaprogramming
Citation preview
Ruby
Vladimir Bystrov
Goals
Learn Ruby basics, OOP and metaprogramming. Compare Ruby to other languages. Show Ruby pros and cons.
Contents
• Overview
• Statements
• OOP
• Metaprogramming
Ruby – Overview
• Object oriented
• Dynamic
• Untyped
• Non commercial
• Productive
Ruby – Overview
Ruby from other languages:
• Java
• Perl
• PHP
Ruby – Overview
Ruby libraries:
• Ruby/DBI
• Rails
• Ruby-IRC
• google image search
• Logging
Ruby – Overview
Advantages:
• OOP
• Dynamic
• Garbage collection
• Metaprogramming
• Exception handling
• Libraries (http://rubyforge.org/)
Ruby – Overview
Disadvantages:
• You can’t control memory allocation process, unable to define data primitives.
• Unable to compile program
• Can’t protect sources
• Bad performance
Ruby – Statements
First programm:
puts “Hello World”
Ruby – Statements
Variables in Ruby always designate references to objects, not the objects themselves.
a = "abcdefg" => "abcdefg"
b = a => "abcdefg"
b => "abcdefg"
a[3] = 'R' => "R"
b => "abcRefg"
Ruby – Statements
Data types:
• number – 23• string – “hello”• boolean – true | false• array – [“str”, 3]• hash array – {“a”=>4, “b”=>56}• range – 0..5• symbol – :symb• proc and blocks – {|x| print x}
Ruby – Statements
Numbers:There are 2 types of numbers in Ruby: integers and
floats (or decimals). There are 2 classes of integer numbers in order to distinguish between their size. So, numbers between -2^62 and 2^62-1 or -2^30 and 2^30-1 belong to the class Fixnum and are stored internally in binary format. Numbers outside those ranges belong to the Bignum class. A numeric literal with a decimal point and/or an exponent is turned into a Float object, corresponding to the native architecture’s double data type.
Ruby – Statements
Numbers examples:
5 # integer number
-12 # negative integer number
4.5 # float number
076 # octal number
0b010 # binary number
0x89 # hexadecimal number
Ruby – Statements
Strings:
str = ‘String’
str = “Another string”
str = %q[String]
str = %Q[Another string]
str = <<EOF
Long long long
multiline text
EOF
Ruby – Statements
Boolean type:
• true• false
Any value evaluate to true, only nil evaluate to false.
Ruby – Statements
Arrays:
• dynamic• heterogeneous• iterators
Ruby – Statements
Ruby – Statements
Arrays examples:
a = [1, 3, 5, 7, 9]
b = [3.14159, "pie", 99]
s = %w[string array init]
r = (1..10).to_a
[1,3,5,7,9].each {|i| puts i}
[1,3,5,7,9].reverse_each {|i| puts i}
Ruby – Statements
Hash arrays:
Hashes (sometimes known as associative arrays, maps, or dictionaries) are similar to arrays in that they are indexed collections of object references. However, while you index arrays with integers, you can index a hash with objects of any type: strings, regular expressions, and so on.
Ruby – Statements
Hash array example:
{”hello” => ”world”,
234 => “mega number!”,
”ruby” => ”rocks”}
Ruby – Statements
Ranges:
Ranges occur everywhere: January to December, 0 to 9, lines 50 through 67, and so on. Ruby supports ranges and allows us to use ranges in a variety of ways:
• Sequences
• Conditions
• Intervals
Ruby – Statements
Ranges as sequences:
"a".."z"
"a"..."z" # equal to "a".."y"
1..100
1...100 # equal to 1..99
Ruby – Statements
Ranges as conditions:
score = 70
result = case score when 0..40: "Fail" when 41..60: "Pass" when 61..70: "Pass with Merit" when 71..100: "Pass with Distinction“ else "Invalid Score" end
puts result
Ruby – Statements
Ranges as intervals:
if ((1..10) === 5)
puts "5 lies in (1..10)"
end
if (('a'..'j') === 'c')
puts "c lies in ('a'..'j')"
end
Ruby – Statements
Symbols:
A symbol in Ruby is an instance of the class Symbol. A symbol is defined by prefixing a colon with an identifier. :name, :id, :user etc. are examples of symbols. Unlike strings, symbols of the same name are initialized and exist in memory only once during a session of ruby.
Ruby – Statements
Symbols usage:
• As keys in hashes
• In Metaprogramming
Ruby – Statements
Proc type:
Proc objects are blocks of code that have been bound to a set of local variables. Once bound, the code may be called in different contexts and still access those variables.
Ruby – Statements
Blocks:
A block does not live on its own - it prepares the code for when it will actually become alive, and only when it is bound and converted to a Proc, it starts living.
Ruby – Statements
Proc examples:
putser = Proc.new {|x| puts x}
putser = lambda {|x| puts x}
putser.call(“Hello”)
Ruby – Statements
Block usage example:
def three_times
yield
yield
yield
end
three_times {puts "Hello"}
Ruby – Statements
Control statements:
• if/unless• case• while/until/loop/for• times/upto/downto
Ruby – Statements
Operator if example:
if num > 0
print “num > 0”
elsif num < 0
print “num < 0”
else
print “num = 0”
end
Ruby – Statements
Operator unless example:
unless num == 0
print “num not equals 0”
else
print “num equals 0”
end
Ruby – Statements
Special if/unless usage example:
print “a < 2” if a < 2
print “num is positive” unless num < 0
Ruby – Statements
Operator case example:
case val
when 0: print “0”
when 1..10: print “from 1 to 10”
else print “more than 10”
end
Ruby – Statements
Operator while example:
num = 0
while num < 10
print num
num++
end
s = 2
s = s*s while s < 1000
Ruby – Statements
Operator until example:
num = 0
until num > 10
print num
num++
end
Ruby – Statements
Operator loop example:
loop do
print “Type something:”
line = gets
break if line =~ /q|Q/
puts line
end
Ruby – Statements
Operator for:
for i in 0..9
print i, “ ”
end
#=> 0 1 2 3 4 5 6 7 8 9
Ruby – Statements
Operators upto, downto and times:
1.upto(5) {|i| print i, “ ”}
#=> 1 2 3 4 5
5.downto(1) {|i| print i, “ ”}
#=> 5 4 3 2 1
10.times {|i| print i, “ ”}
#=> 0 1 2 3 4 5 6 7 8 9
Ruby – Statements
Exceptions handling:
begin
# ...
rescue RuntimeError => e
# handle concrete error
else
# handle unexpected error
ensure
# runs in any case
end
raise ArgumentError, “Incorrect argument", caller
# caller – returns stack trace
Ruby – OOP
• Methods
• Classes
• Singletons
• Inheritance
• Modules
• Encapsulation
Ruby – OOP
Methods:
def method
print “hello”
end
In Ruby you can override operators like methods.
def +(val)
@val + val
end
Ruby – OOP
Classes:
class Test
def initialize(val)
@val = val
end
def out_value
print @val
end
end
Ruby – OOP
Instance variables:
class Test
@name = “Easy Jet”
def name
@name
end
def name=(val)
@name = val
end
end
Ruby – OOP
In Ruby you can create getters and setters using methods:
• attr• attr_reader• attr_writer• attr_accessor
Ruby – OOP
Method attr:
class Test
attr :name, true
end
Ruby – OOP
Method attr_reader:
class Test
attr_reader :name, :phone
end
Ruby – OOP
Method attr_writer:
class Test
attr_writer :name, :phone
end
Ruby – OOP
Method attr_accessor:
class Test
attr_accessor :name, :phone
end
Ruby – OOP
Class variables and methods:
class Test
@@variable = “something”
Test.output
print “class method”
end
end
Ruby – OOP
Singleton:
Singleton classes, not to be confused with the singleton design pattern. The name itself is confusing, leading people to create alternative names such as: object-specific classes, anonymous classes, and virtual classes. Anonymous classes is one of the better names.
Ruby – OOP
Singleton example:
class Singleton
end
s = Singleton.new
class << s def s.handle
print “singleton method”
endend
Ruby – OOP
Inheritance:
class Base
def method
print “hello”
end
end
class Child < Base
attr_accessor :name
end
Ruby – OOP
Modules (Mixin):
module TestModule
def out
print “mixin”
end
end
class Test
include TestModule
end
Ruby – OOP
Encapsulation:
• private• protected• public
class Test
private
def priv_method
// do something
end
end
Ruby – Metaprogramming
Duck typing:
Duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface. The name of the concept refers to the duck test, attributed to James Whitcomb Riley, which may be phrased as follows: “If it walks like a duck and quacks like a duck, I would call it a duck”.
Ruby – Metaprogramming
Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data, or that do part of the work at runtime that would otherwise be done at compile time. In many cases, this allows programmers to get more done in the same amount of time as they would take to write all the code manually, or it gives programs greater flexibility to efficiently handle new situations without recompilation.
Ruby – Metaprogramming
Dynamic code interpretation:
• eval• class_eval, module_eval• instance_eval
Foo = Class.new
a = %q[def out() p "hello" end]
Foo.class_eval(a)
foo = Foo.new
foo.out #=> “hello”
Ruby – Metaprogramming
Get and set instance variables:
class Tester
@name
end
x = Tester.new
p x.instance_variable_get("@name") #=> nil
x.instance_variable_set("@name", "hello")
p x.instance_variable_get("@name") #=> "hello"
Ruby – Metaprogramming
Dynamic method definition:
class Tester
def new_method(name, &block)
self.class.send(:define_method, name, &block)
end
end
x = Tester.new
x.new_method(:out) {p "hello"}
x.out #=> “hello”
Ruby – Metaprogramming
Remove definitions:
• undef_method• remove_method
class Array
remove_method :size
end
x = [1,2,3]
p x.size #=> Error
Ruby – Metaprogramming
Get list of defined objects, class methods:
• constants• ancestors• class_variables• included_modules• public_instance_methods• private_instance_methods• protected_instance_methods• superclass
Ruby – Metaprogramming
Get list of defined objects, instance methods:
• instance_variables• methods• public_methods• private_methods• protected_methods• singleton_methods
Ruby – Metaprogramming
Get class information:
• class• object_id• kind_of?• instance_of?• respond_to?
Ruby – Metaprogramming
View stack of calls:
def func1
puts caller[0]
end
def func2
func1
end
func2 #=> prints: somefile.rb:6:in “func2”
Ruby – Metaprogramming
Iterate object space:
ObjectSpace.each_object do |obj|
p obj.class
end
You can provide parameter for each_object (class or module), to narrow output.
Ruby – Metaprogramming
Handle missing methods calls:
In ruby, when you call a method that doesn't actually exist on that object, the object always invokes the method_missing method instead. This is one of ruby's cool metaprogramming features: it lets you decide yourself how to handle what would have otherwise been an error.
Ruby – Metaprogramming
Handle missing methods calls:
class Tester
def method_missing(method, *args)
system(method.to_s, *args)
end
end
t = Tester.new
t.dir
Ruby – Metaprogramming
Observe changes in objects or class definitions:
•inherited•included•method_added
class Test
def Test.method_added(method)
p "new method added [#{method}]"
end
end
Questions