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,  &quot;pie&quot; , 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: &quot;a&quot; .. &quot;z&quot;   &quot;a&quot; ... &quot;z&quot;   #  equal to  &quot;a&quot;..&quot;y&quot;   1..100  1...100  #  equal to  1..99
Ruby – Statements Ranges as conditions: score = 70  result =  case  score  when  0..40:  &quot;Fail&quot;  when  41..60:  &quot;Pass&quot;  when  61..70:  &quot;Pass with Merit&quot;  when  71..100:  &quot;Pass with Distinction“ else   &quot;Invalid Score&quot;  end   puts  result
Ruby – Statements Ranges as intervals: if  ((1..10) === 5)  puts   &quot;5 lies in (1..10)&quot;  end   if  (( 'a' .. 'j' ) ===  'c' )  puts   &quot;c lies in ('a'..'j')&quot;  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   &quot;Hello&quot; }
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 &quot; , 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” end end
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 &quot;hello&quot; 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( &quot;@name&quot; )  #=> nil x.instance_variable_set( &quot;@name&quot; ,  &quot;hello&quot; ) p x.instance_variable_get( &quot;@name&quot; )  #=> &quot;hello&quot;
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  &quot;hello&quot; } 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  &quot;new method added [#{method}]&quot; end end
Resources http://www.ruby-lang.org/en/
Questions

Ruby

  • 1.
  • 2.
    Goals Learn Rubybasics, OOP and metaprogramming. Compare Ruby to other languages. Show Ruby pros and cons.
  • 3.
    Contents Overview StatementsOOP Metaprogramming
  • 4.
    Ruby – OverviewObject oriented Dynamic Untyped Non commercial Productive
  • 5.
    Ruby – OverviewRuby from other languages: Java Perl PHP
  • 6.
    Ruby – OverviewRuby libraries: Ruby/DBI Rails Ruby-IRC google image search Logging
  • 7.
    Ruby – OverviewAdvantages: OOP Dynamic Garbage collection Metaprogramming Exception handling Libraries ( http://rubyforge.org/ )
  • 8.
    Ruby – OverviewDisadvantages: You can’t control memory allocation process, unable to define data primitives. Unable to compile program Can’t protect sources Bad performance
  • 9.
    Ruby – StatementsFirst programm : puts “Hello World”
  • 10.
    Ruby – StatementsVariables in Ruby always designate references to objects, not the objects themselves. a = &quot;abcdefg&quot; => &quot;abcdefg&quot; b = a => &quot;abcdefg&quot; b => &quot;abcdefg&quot; a[3] = 'R' => &quot;R&quot; b => &quot;abcRefg&quot;
  • 11.
    Ruby – StatementsData 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}
  • 12.
    Ruby – StatementsNumbers : 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.
  • 13.
    Ruby – StatementsNumbers examples : 5 # integer number -12 # negative integer number 4.5 # float number 076 # octal number 0b010 # binary number 0x89 # hexadecimal number
  • 14.
    Ruby – StatementsStrings : str = ‘String’ str = “Another string” str = %q[ String ] str = % Q[ Another string ] str = <<EOF Long long long multiline text EOF
  • 15.
    Ruby – StatementsBoolean type : true false Any value evaluate to true , only nil evaluate to false .
  • 16.
    Ruby – StatementsArrays : dynamic heterogeneous iterators
  • 17.
  • 18.
    Ruby – StatementsArrays examples: a = [1, 3, 5, 7, 9] b = [3.14159, &quot;pie&quot; , 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}
  • 19.
    Ruby – StatementsHash 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.
  • 20.
    Ruby – StatementsHash array example : { ”hello” => ”world” , 234 => “ mega number ! ” , ” ruby” = > ”rocks” }
  • 21.
    Ruby – StatementsRanges: 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
  • 22.
    Ruby – StatementsRanges as sequences: &quot;a&quot; .. &quot;z&quot; &quot;a&quot; ... &quot;z&quot; # equal to &quot;a&quot;..&quot;y&quot; 1..100 1...100 # equal to 1..99
  • 23.
    Ruby – StatementsRanges as conditions: score = 70 result = case score when 0..40: &quot;Fail&quot; when 41..60: &quot;Pass&quot; when 61..70: &quot;Pass with Merit&quot; when 71..100: &quot;Pass with Distinction“ else &quot;Invalid Score&quot; end puts result
  • 24.
    Ruby – StatementsRanges as intervals: if ((1..10) === 5) puts &quot;5 lies in (1..10)&quot; end if (( 'a' .. 'j' ) === 'c' ) puts &quot;c lies in ('a'..'j')&quot; end
  • 25.
    Ruby – StatementsSymbols: 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.
  • 26.
    Ruby – StatementsSymbols usage: As keys in hashes In Metaprogramming
  • 27.
    Ruby – StatementsProc 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.
  • 28.
    Ruby – StatementsBlocks: 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.
  • 29.
    Ruby – StatementsProc examples: putser = Proc. new {|x| puts x} putser = lambda {|x| puts x} putser.call( “Hello” )
  • 30.
    Ruby – StatementsBlock usage example: def three_times yield yield yield end three_times { puts &quot;Hello&quot; }
  • 31.
    Ruby – StatementsControl statements : if/unless case while/until/loop/for times/upto/downto
  • 32.
    Ruby – StatementsOperator if example: if num > 0 print “num > 0” elsif num < 0 print “num < 0” else print “num = 0” end
  • 33.
    Ruby – StatementsOperator unless example: unless num == 0 print “num not equals 0” else print “num equals 0” end
  • 34.
    Ruby – StatementsSpecial if/unless usage example: print “a < 2” if a < 2 print “num is positive” unless num < 0
  • 35.
    Ruby – StatementsOperator case example : case val when 0: print “0” when 1..10: print “from 1 to 10” else print “more than 10” end
  • 36.
    Ruby – StatementsOperator while example : num = 0 while num < 10 print num num++ end s = 2 s = s*s while s < 1000
  • 37.
    Ruby – StatementsOperator until example : num = 0 until num > 10 print num num++ end
  • 38.
    Ruby – StatementsOperator loop example : loop do print “Type something:” line = gets break if line =~ /q|Q/ puts line end
  • 39.
    Ruby – StatementsOperator for : for i in 0..9 print i, “ ” end #=> 0 1 2 3 4 5 6 7 8 9
  • 40.
    Ruby – StatementsOperators 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
  • 41.
    Ruby – StatementsExceptions handling : begin # ... rescue RuntimeError => e # handle concrete error else # handle unexpected error ensure # runs in any case end raise ArgumentError, “ Incorrect argument &quot; , caller # caller – returns stack trace
  • 42.
    Ruby – OOPMethods Classes Singletons Inheritance Modules Encapsulation
  • 43.
    Ruby – OOPMethods : def method print “hello” end In Ruby you can override operators like methods . def +( val ) @val + val end
  • 44.
    Ruby – OOPClasses: class Test def initialize(val) @val = val end def out_value print @val end end
  • 45.
    Ruby – OOPInstance variables : class Test @name = “Easy Jet” def name @name end def name=(val) @name = val end end
  • 46.
    Ruby – OOPIn Ruby you can create getters and setters using methods : attr attr_reader attr_writer attr_accessor
  • 47.
    Ruby – OOPMethod attr : class Test attr : name, true end
  • 48.
    Ruby – OOPMethod attr_reader : class Test attr_reader :name, :phone end
  • 49.
    Ruby – OOPMethod attr_writer : class Test attr_writer :name, :phone end
  • 50.
    Ruby – OOPMethod attr_accessor : class Test attr_accessor :name, :phone end
  • 51.
    Ruby – OOPClass variables and methods: class Test @@variable = “something” Test.output print “class method” end end
  • 52.
    Ruby – OOPSingleton: 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.
  • 53.
    Ruby – OOPSingleton example: class Singleton end s = Singleton. new class << s def s.handle print “singleton method” end end
  • 54.
    Ruby – OOPInheritance: class Base def method print “hello” end end class Child < Base attr_accessor :name end
  • 55.
    Ruby – OOPModules ( Mixin ) : module TestModule def out print “mixin” end end class Test include TestModule end
  • 56.
    Ruby – OOPEncapsulation: private protected public class Test private def priv_method // do something end end
  • 57.
    Ruby – MetaprogrammingDuck 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”.
  • 58.
    Ruby – MetaprogrammingMetaprogramming 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.
  • 59.
    Ruby – MetaprogrammingDynamic code interpretation : eval class_eval, module_eval instance_eval Foo = Class.new a = %q[ def out() p &quot;hello&quot; end ] Foo.class_eval(a) foo = Foo.new foo.out #=> “hello”
  • 60.
    Ruby – MetaprogrammingGet and set instance variables : class Tester @name end x = Tester. new p x.instance_variable_get( &quot;@name&quot; ) #=> nil x.instance_variable_set( &quot;@name&quot; , &quot;hello&quot; ) p x.instance_variable_get( &quot;@name&quot; ) #=> &quot;hello&quot;
  • 61.
    Ruby – MetaprogrammingDynamic 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 &quot;hello&quot; } x.out #=> “hello”
  • 62.
    Ruby – MetaprogrammingRemove definitions : undef_method remove_method class Array remove_method :size end x = [1,2,3] p x.size #=> Error
  • 63.
    Ruby – MetaprogrammingGet list of defined objects, class methods : constants ancestors class_variables included_modules public_instance_methods private_instance_methods protected_instance_methods superclass
  • 64.
    Ruby – MetaprogrammingGet list of defined objects, instance methods : instance_variables methods public_methods private_methods protected_methods singleton_methods
  • 65.
    Ruby – MetaprogrammingGet class information : class object_id kind_of? instance_of? respond_to?
  • 66.
    Ruby – MetaprogrammingView stack of calls : def func1 puts caller[0] end def func2 func1 end func2 #=> prints : somefile.rb:6:in “func2”
  • 67.
    Ruby – MetaprogrammingIterate object space : ObjectSpace.each_object do |obj| p obj.class end You can provide parameter for each_object (class or module), to narrow output .
  • 68.
    Ruby – MetaprogrammingHandle 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. 
  • 69.
    Ruby – MetaprogrammingHandle missing methods calls : class Tester def method_missing(method, *args) system(method.to_s, *args) end end t = Tester. new t.dir
  • 70.
    Ruby – MetaprogrammingObserve changes in objects or class definitions : inherited included method_added class Test def Test.method_added(method) p &quot;new method added [#{method}]&quot; end end
  • 71.
  • 72.