Ruby

72
Ruby Vladimir Bystrov

description

Ruby basics, OOP, metaprogramming

Transcript of Ruby

Page 1: Ruby

Ruby

Vladimir Bystrov

Page 2: Ruby

Goals

Learn Ruby basics, OOP and metaprogramming. Compare Ruby to other languages. Show Ruby pros and cons.

Page 3: Ruby

Contents

• Overview

• Statements

• OOP

• Metaprogramming

Page 4: Ruby

Ruby – Overview

• Object oriented

• Dynamic

• Untyped

• Non commercial

• Productive

Page 5: Ruby

Ruby – Overview

Ruby from other languages:

• Java

• Perl

• PHP

Page 6: Ruby

Ruby – Overview

Ruby libraries:

• Ruby/DBI

• Rails

• Ruby-IRC

• google image search

• Logging

Page 7: Ruby

Ruby – Overview

Advantages:

• OOP

• Dynamic

• Garbage collection

• Metaprogramming

• Exception handling

• Libraries (http://rubyforge.org/)

Page 8: Ruby

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

Page 9: Ruby

Ruby – Statements

First programm:

puts “Hello World”

Page 10: Ruby

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"

Page 11: Ruby

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}

Page 12: Ruby

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.

Page 13: Ruby

Ruby – Statements

Numbers examples:

5 # integer number

-12 # negative integer number

4.5 # float number

076 # octal number

0b010 # binary number

0x89 # hexadecimal number

Page 14: Ruby

Ruby – Statements

Strings:

str = ‘String’

str = “Another string”

str = %q[String]

str = %Q[Another string]

str = <<EOF

Long long long

multiline text

EOF

Page 15: Ruby

Ruby – Statements

Boolean type:

• true• false

Any value evaluate to true, only nil evaluate to false.

Page 16: Ruby

Ruby – Statements

Arrays:

• dynamic• heterogeneous• iterators

Page 17: Ruby

Ruby – Statements

Page 18: Ruby

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}

Page 19: Ruby

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.

Page 20: Ruby

Ruby – Statements

Hash array example:

{”hello” => ”world”,

234 => “mega number!”,

”ruby” => ”rocks”}

Page 21: Ruby

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

Page 22: Ruby

Ruby – Statements

Ranges as sequences:

"a".."z"

"a"..."z" # equal to "a".."y"

1..100

1...100 # equal to 1..99

Page 23: Ruby

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

Page 24: Ruby

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

Page 25: Ruby

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.

Page 26: Ruby

Ruby – Statements

Symbols usage:

• As keys in hashes

• In Metaprogramming

Page 27: Ruby

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.

Page 28: Ruby

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.

Page 29: Ruby

Ruby – Statements

Proc examples:

putser = Proc.new {|x| puts x}

putser = lambda {|x| puts x}

putser.call(“Hello”)

Page 30: Ruby

Ruby – Statements

Block usage example:

def three_times

yield

yield

yield

end

three_times {puts "Hello"}

Page 31: Ruby

Ruby – Statements

Control statements:

• if/unless• case• while/until/loop/for• times/upto/downto

Page 32: Ruby

Ruby – Statements

Operator if example:

if num > 0

print “num > 0”

elsif num < 0

print “num < 0”

else

print “num = 0”

end

Page 33: Ruby

Ruby – Statements

Operator unless example:

unless num == 0

print “num not equals 0”

else

print “num equals 0”

end

Page 34: Ruby

Ruby – Statements

Special if/unless usage example:

print “a < 2” if a < 2

print “num is positive” unless num < 0

Page 35: Ruby

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

Page 36: Ruby

Ruby – Statements

Operator while example:

num = 0

while num < 10

print num

num++

end

s = 2

s = s*s while s < 1000

Page 37: Ruby

Ruby – Statements

Operator until example:

num = 0

until num > 10

print num

num++

end

Page 38: Ruby

Ruby – Statements

Operator loop example:

loop do

print “Type something:”

line = gets

break if line =~ /q|Q/

puts line

end

Page 39: Ruby

Ruby – Statements

Operator for:

for i in 0..9

print i, “ ”

end

#=> 0 1 2 3 4 5 6 7 8 9

Page 40: Ruby

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

Page 41: Ruby

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

Page 42: Ruby

Ruby – OOP

• Methods

• Classes

• Singletons

• Inheritance

• Modules

• Encapsulation

Page 43: Ruby

Ruby – OOP

Methods:

def method

print “hello”

end

In Ruby you can override operators like methods.

def +(val)

@val + val

end

Page 44: Ruby

Ruby – OOP

Classes:

class Test

def initialize(val)

@val = val

end

def out_value

print @val

end

end

Page 45: Ruby

Ruby – OOP

Instance variables:

class Test

@name = “Easy Jet”

def name

@name

end

def name=(val)

@name = val

end

end

Page 46: Ruby

Ruby – OOP

In Ruby you can create getters and setters using methods:

• attr• attr_reader• attr_writer• attr_accessor

Page 47: Ruby

Ruby – OOP

Method attr:

class Test

attr :name, true

end

Page 48: Ruby

Ruby – OOP

Method attr_reader:

class Test

attr_reader :name, :phone

end

Page 49: Ruby

Ruby – OOP

Method attr_writer:

class Test

attr_writer :name, :phone

end

Page 50: Ruby

Ruby – OOP

Method attr_accessor:

class Test

attr_accessor :name, :phone

end

Page 51: Ruby

Ruby – OOP

Class variables and methods:

class Test

@@variable = “something”

Test.output

print “class method”

end

end

Page 52: Ruby

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.

Page 53: Ruby

Ruby – OOP

Singleton example:

class Singleton

end

s = Singleton.new

class << s def s.handle

print “singleton method”

endend

Page 54: Ruby

Ruby – OOP

Inheritance:

class Base

def method

print “hello”

end

end

class Child < Base

attr_accessor :name

end

Page 55: Ruby

Ruby – OOP

Modules (Mixin):

module TestModule

def out

print “mixin”

end

end

class Test

include TestModule

end

Page 56: Ruby

Ruby – OOP

Encapsulation:

• private• protected• public

class Test

private

def priv_method

// do something

end

end

Page 57: Ruby

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”.

Page 58: Ruby

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.

Page 59: Ruby

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”

Page 60: Ruby

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"

Page 61: Ruby

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”

Page 62: Ruby

Ruby – Metaprogramming

Remove definitions:

• undef_method• remove_method

class Array

remove_method :size

end

x = [1,2,3]

p x.size #=> Error

Page 63: Ruby

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

Page 64: Ruby

Ruby – Metaprogramming

Get list of defined objects, instance methods:

• instance_variables• methods• public_methods• private_methods• protected_methods• singleton_methods

Page 65: Ruby

Ruby – Metaprogramming

Get class information:

• class• object_id• kind_of?• instance_of?• respond_to?

Page 66: Ruby

Ruby – Metaprogramming

View stack of calls:

def func1

puts caller[0]

end

def func2

func1

end

func2 #=> prints: somefile.rb:6:in “func2”

Page 67: Ruby

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.

Page 68: Ruby

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. 

Page 69: Ruby

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

Page 70: Ruby

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

Page 71: Ruby

Resources

http://www.ruby-lang.org/en/

Page 72: Ruby

Questions