SlideShare a Scribd company logo
1 of 76
Download to read offline
Ruby
An introduction to the Ruby programming language

               LPOO — MIEIC — FEUP




                     May 2011
@goncalossilva
Ruby
     Created by Yukihiru “Matz” Matsumoto, in Japan
     Perl + SmallTalk + Eiffel + Ada + Lisp = Ruby


“I wanted a scripting language that was more powerful than Perl, and more object-oriented than Python.” — matz
Ruby
  Interpreted language, with many implementations: YARV , Rubinius , JRuby , etc

  Functional, object-oriented, imperative and reflective

  Dynamically typed, with automatic garbage collection, exception handling and
built-in unit testing

  Optimized for programmer productivity and happiness
Basics
Methods

def hello_world()
  return "Hello world!"
end

hello_world()
Methods

def hello_world # no need for ()
  "Hello world!" # implicit return
end

hello_world # no need for ()
Classes

class HelloWorld
  def say
    "Hello world done right!"
  end
end

hello_world_object = HelloWorld.new
hello_world_object.say
It's object-oriented

class Lecture
  def initialize(name = "TBA", duration_in_minutes = 60)
    @name = name
    @duration = duration_in_minutes/60.0;
  end

  def description
    "Name: #{@name}nDuration: #{@duration} hours"
  end
end

lecture = Lecture.new("Ruby", 45)
lecture.description
It's really object-oriented

// Java
maximum = Math.max(1, 3)


# Ruby
maximum = [1, 3].max
It's really object-oriented

# Python
positive = abs(num)


# Ruby
positive = num.abs
It's really object-oriented

// C
length = strlen(name)


# Ruby
length = name.length
It's really object-oriented
In Ruby, all functions and most operators are methods of an object

In Python, for instance, some functions are procedural
Classes themselves are instances of Class
It's really object-oriented
Ruby has a permanent notion of the current object : self

self controls how Ruby accesses instance variables

All method calls are made on some object, called the receiver

If no receiver is specified, self is used — it is implicit!
It's really object-oriented

# self is "main", an instance of Object
class MyClass
  # self is MyClass

  def my_method
    # self will depend on the receiver for this method
  end
end

# self is "main" again, so my_object exists in the main scope
my_object = MyClass.new

# explicit receiver, so self will be my_object inside my_method
my_object.my_method
Arrays
 Store indexed collections of objects accessible through an integer key

 Can contain objects with different classes simultaneously


# array
a = [1, "second", 3.14]
a[2]
Hashes
  Store indexed collections of objects accessible through a key which can be any
object

  Slightly less efficient but much more flexible


# hash
h = {
  "string"    =>   [3,4,5],
  2           =>   "everything can be a value!",
  [1,2]       =>   "everything can be a key!"
}
h[[1,2]]
Symbols
 A significant name, generally a static variable


// java
static final int NORTH = 1;
// ... more code
move(NORTH);



# ruby
move(:north)


 No need to predeclare these constants, they are unique


return true if direction == :north
Control Structures

# if
if score.between?(100, 199)
  puts "You rock!"
elsif score < 50
  puts "You suck!"
else
  puts "Meh"
end

# while
while score < 100
  puts "You're almost there! Try again..."
  # ...
end

# more goodness with unless, until, case, for, etc


# and awesome shortcuts like statement modifiers
puts "You cheated!" if score >= 200
Blocks and Iterators
Blocks
 A chuck of code enclosed between { } or do/end keywords
 Similar to the concept of anonymous methods

 Can take parameters

 Can be passed to methods as arguments (at the end, like an extra parameter)


sum = 0
(1..5).each do |n| # same as [1,2,3,4,5]
  sum += n
end
sum


# same thing with { }
sum = 0
(1..5).each { |n| sum += n }
sum
Blocks as Objects
 Can be converted into objects
 Can be stored in variables, pass them around, invoke them whenever you want

 Great for implementing callbacks, dispatch tables, etc


class BlockAsObject
  def store_block(&my_block)
    @stored_block = my_block # converted to Proc
  end

  def use_block(parameter)
    @stored_block.call(parameter)
  end
end

foo = BlockAsObject.new
foo.store_block { |param| "The block was called with " + param }
foo.use_block("delay")
Blocks as Closures
 They can use local variables from the surrounding scope


def powers_of_2_proc
  value = 1
  lambda { value += value }
end

powers_of_2 = powers_of_2_proc

powers_of_2.call     #   2
powers_of_2.call     #   4
powers_of_2.call     #   will return 8!


 So, powers_of_2_proc returns a Proc that references value
 When the block is called, value is out of scope

 The block is still able to access it (and will be for the remaining life of this block)
Iterators
  In many languages, collections implement methods to generate external iterator
objects


// C++
for (std::vector<int>::iterator i=list.begin(); i!=list.end(); i++) {
  // code
}
Iterators
  In many languages, collections implement methods to generate external iterator
objects


// C#
IEnumerator<int> i = list.GetEnumerator();
while (i.MoveNext()) {
  // code
}
Iterators
  In many languages, collections implement methods to generate external iterator
objects


// Java
Iterator i = list.iterator();
while (i.hasNext()) {
  // code
}
Iterators
 When coming from other languages, many people iterate collections like this:


# familiar?
for i in 0..2
  number = array[i][0]
  word   = array[i][1]

  puts "#{word}: #{number}"
end
Iterators
  However, there's another approach:


# the "ruby way", with a lot less coupling
array.each do |word, number|
  puts "#{word}: #{number}"
end


 The “Ruby way” is different: an iterator is internal to the collection... it's just a
method that calls yield every time it generates a new value
Iterators
 Ruby provides a lot of useful iterators: each, map , inject , etc

 But you can build your own


def fib(max)
  i1, i2 = 1, 1 # parallel assignment
  while i1 <= max
    yield i1
    i1, i2 = i2, i1+i2
  end
end

result = ""
fib(1337) { |n| result += "#{n} " }
result
Iterators
Ruby's internal iterators aren't necessarily the best solution
What if you need the iterator to be an object?

What if you want to iterate multiple collections simultaneously?
Enumerators
 When iterators aren't suitable, you can resort to enumerators
 To put it simply, an enumerator is an external iterator


array = ["my", 1337, "array"]
enumerator = array.to_enum # same as "enumerator = array.each"

enumerator.next # returns "my" and moves to the next element
enumerator.next
Enumerators
 Most internal iterators are can be used as enumerators


string = "le fu"
enumerator = string.each_char

enumerator.next # returns "l" and moves to the next char
enumerator.next # returns "e" and moves to the next char
Containers, containers, containers!
  Blocks and iterators are core concepts of Ruby

  With practice, you'll start building classes that iterate over their contents instead
of using the conventional looping constructs

  It might seem complicated at first, but you'll start using these features naturally

  Easy to read and maintain
Sharing
Functionality
Inheritance

class SuperClass
  def hello_world
    "Hello world!"
  end
end

class SubClass < SuperClass
end

superclass = SuperClass.new
subclass   = SubClass.new

"Hello world from the superclass: #{superclass.hello_world}n" +
"Hello world from the subclass : #{subclass.hello_world}"
Inheritance
Single inheritance, unlike C++
Top-level classes are subclasses of Object , which is a subclass of BasicObject

Classes have built-in functionality because they inherited it!
Modules
 Modules provide a namespace, avoiding name collisions


module MyModule # a module has it all
  MY_CONSTANT = "my constant" # constants

 def my_method # methods
 end

  class MyClass # and classes
  end
end

namespaced = MyModule::MyClass.new


 Modules have another wonderful use: mixins
Mixins and Inheritance
  Some OO languages support multiple inheritance (C++, Lisp, Python, etc)

  This is very powerful, but can be troublesome because of inheritance ambiguity

  Ruby offers a great compromise: the simplicity of single inheritance and the
power of multiple inheritance
Mixins
 include is used to mix modules into classes or other modules



module ToBeIncluded
  def foo
    "bar"
  end
end

class MyClass
  include ToBeIncluded
end

object = MyClass.new
object.foo
Mixins
 extend is used to add instance methods to a given object



module ToBeIncluded
  def foo
    "bar"
  end
end

class MyClass
end

object = MyClass.new
object.extend ToBeIncluded
object.foo
Mixins
 extend is also used to mix instance methods into a class



module ToBeIncluded
  def foo
    "bar"
  end
end

class MyClass
  extend ToBeIncluded
end

MyClass.foo
Mixins

module StringHelpers                       class Over9000Number < Number
  def stringify                              include StringHelpers
    if self.value > 9000
      "Over 9000!"                           def initialize(value)
    else                                       super(value + 9000)
      "Meh"                                  end
    end
  end                                        def status
end                                            "Current status: "+stringify
                                             end
class Number                               end
  attr_reader :value
                                           number = Over9000Number.new(42)
  def initialize(value)                    number.status
    @value = value                         # => "Current status: Over 9000!"
  end
end



 Inherit from one class, include functionality from multiple modules — mixins !
Inheritance, Mixins and Design
Ruby allows you to right code once and inject it into multiple places

When to use each?
    Inheritance

         You should be able to replace a parent object with a child object, honoring
      its contract

        A child object is a kind of the parent (an apple is a fruit)

        In the real world, strict hierarchies are restrictive... we need composition!

    Mixins

        For composition: A has a B, or A uses a B

        Exclusively using mixins can be messy — both should be combined
Inheritance, Mixis and Design
 Each of them serves its purpose, our job is to use the appropriately

 None of these make any sense:


class Person < DataWrapper
end

class Banana
  include FruitProperties
end


 Think before you type
Reflection
Reflection
    Ruby is very powerful when it comes to examining the aspects of a program
  within itself
     It can discover information about:
           What objects exist

           All class hierarchies

           Attributes and methods of all objects

           Information about methods


“When you introspect, you think about your thoughts and feelings. This is interesting because you're using thought to
                                        analyze thought.” — Dave Thomas
Reflection and Objects
 You can transverse all living objects:


ObjectSpace.each_object(Float) { |x| puts x }
Reflection and Objects
 You can look inside objects:


[1,2,3].methods[0..4]


[1,2,3].respond_to?(:to_s)


[1,2,3].kind_of?(Hash)
Reflection and Objects
 You can invoke any method by name using send :


a = [1,2,3]
a.send(a.private_methods.first.to_sym) # "initialize"
a # now it's empty!
Reflection and Objects
 Another way is to use the Method class:


a = [1,2,3]
constructor = a.method(:initialize)
constructor.call
a


 You get a Method object which you can store, pass around and call anytime!
Reflection and Classes
 It's also possible to look inside classes:


String.ancestors # all superclasses and mixed-in modules
Reflection and Classes
 It's also possible to look inside classes:


klass = String
result = klass.to_s
begin
  klass = klass.superclass
  result += " < " + klass.to_s
end while klass.superclass
result
Reflection and Classes
 It's also possible to look inside classes:


Fixnum.constants


Fixnum.class_variables


Fixnum.singleton_methods(false)


Fixnum.instance_methods(false) # private/protected/public prefix
Reflection and the Program's
               Execution
  Ruby let's you look at the interpreter while it executes your code


set_trace_func lambda { |event, file, line, id, binding, classname|
  printf "%8s %s:%s-2d %-15sn", event, file, line, classname, id
}

# all code is traced from now on


 And you can also get the current call stack by using calling caller on your
methods
Reflection and the Program's
               Execution
  You can even get the current source file being executed with the __FILE__ special
variable, leading to an interesting Quine :


print File.read(__FILE__)


  A program that outputs itself!
Metaprogramming
Metaprogramming
  Ruby code can modify aspects of its own structure at runtime and it makes it all
easy

  You've seen it before on this presentation: remember include and extend? Ruby is
effectively injecting their code into their receiver
Singleton Methods
  Ruby lets you define methods specific to a particular object


person = "person" # String object
def person.say_hi
  "Hi!"
end
person.say_hi


  Magic? No. Ruby created an anonymous class (often called singleton class) based
on String and added the method say_hi to it
Singleton Class
 There are other ways of creating methods in an object's singleton class


person = "person"
class << person
  def say_hi
    "Hi there!"
  end
end
person.say_hi
Inherited Visibility
 The visibility of an inherited method can be changed


class SuperClass
  private
    def my_private_method
      "U can't touch this"
    end
end

class SubClass < SuperClass
  public :my_private_method
end

object = SubClass.new
object.my_private_method # not so private anymore
Inherited Visibility
  What's really happening is that Ruby is inserting a hidden proxy method in the
subclass that invokes the original method with super


class SubClass < SuperClass
  def my_private_method
    super
  end

  public :my_private_method
end


  super calls can access the parent's method regardless of its visibility
Defining Methods
  Ruby allows you to define methods at runtime using define_method


class BabyInfo
  ["cry", "eat", "poop"].each do |baby_action|
    define_method(baby_action) do
      "Of course, babies #{baby_action}"
    end
  end
end

baby_info = BabyInfo.new
baby_info.cry


  Methods can also be blocked/removed by calling undef_method and remove_method,
respectively
Class-level Macros
 Ruby has a few class-level macros that generate code behind the scenes


class Laptop
  attr_accessor :memory # injects a getter/setter for "memory"
end


 If you've used Ruby on Rails, you've probably dealt with associations


class Post < ActiveRecord::Base
  has_many :comments
end
Eval
 Similarly to other languages, eval evaluates the passed Ruby expression(s)


course = "LPOO"
eval "'Hello ' + course + '!'"
Instance eval
  instance_eval allows you to evaluate Ruby expression(s) in the context of an
instance


string = "cool man cool"
string.instance_eval "def shout; self.upcase; end"
string.shout


  Remember: classes are instances of Class, so you can also use instance_eval with
them:


Fixnum.instance_eval "def ten; 10; end"
Fixnum.ten
Class eval
  As the name implies, class_eval can only be used with classes

  It evaluates the code as if you were in the context of the class definition


String.class_eval do
  def shout
    self.upcase
  end
end
string = "cool man cool"
string.shout


  Note: eval, instance_eval and class_eval can take blocks as arguments as shown
above
Eval evilness
eval is slow

eval is dangerous

eval doesn't generally make sense, given all other metaprogramming facilities
Callbacks
  Ruby provides hook methods , called by the interpreter when a specific event
occurs
  Among all available hook methods —also known as callbacks —are:
      Method-related hooks: method_added, method_missing, method_removed, etc

      Class/Module-related hooks: const_missing, extended, included, inherited, etc

      Object marshaling and coercion hooks
Callbacks: method_missing
 Ruby allows you to act upon calls to undefined methods by using method missing


class BabyInfo
  ["cry", "eat", "poop"].each do |baby_action|
    define_method(baby_action) do
      "Of course, babies #{baby_action}"
    end
  end

  def method_missing(name, *args, &block)
    "Nope, babies don't #{name}"
  end
end

baby_info = BabyInfo.new
baby_info.surf
Callbacks: inherited
 Ruby allows your classes to act when they're subclassed


class SuperClass
  @children = [] # class variable

 def self.inherited(child)
   @children << child
 end

  def self.children
    @children
  end
end
Callback: method calls
  Ruby allows you to intercept calls to specific methods:


class Object
  alias_method :old_to_s, :to_s
  def to_s
    result = self.old_to_s
    "Your modified to_s returned this (should be '"+result+"')"
  end
end

object = Object.new
object.to_s


  This isn't a direct hook: you're copying the original method and inserting a hook
by yourself
Wrapping Up
Ruby
  Ruby is an incredibly powerful language

  Many successful projects/products use it at their core: Ruby on Rails, God,
Redmine, etc

  You can add and remove code in a running process, redefine methods on the fly,
change their scope

  You can even modify basic types like String, Float or even Class and Object

   After using it for a while, you'll notice the lack of flexibility on static languages
like C++ or half-static languages like Java
Ruby
 This presentation, for instance, is running on a Sinatra application
 And most of the shown code was executed in real time

 No? Then check this out:


class Lecture
  def initialize(name = "TBA")
    @name = name
  end

  def finish
    "Finished at #{(Time.now.utc+3600).strftime('%H:%M:%S')}!"
  end
end

lecture = Lecture.new("Ruby")
lecture.finish
More
Books:
       Programming Ruby 1.9 by Dave Thomas

       Metaprogramming Ruby by Paolo Perrotta

Mailing lists:
       Ruby-Talk (subscribe through Ruby's website)

       Ruby-pt (Google Groups)

IRC:
       #ruby and #ruby-pt on Freenode
?

More Related Content

What's hot

Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To ScalaPeter Maas
 
Class 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented ProgrammingClass 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented ProgrammingAhmed Swilam
 
Xbase - Implementing Domain-Specific Languages for Java
Xbase - Implementing Domain-Specific Languages for JavaXbase - Implementing Domain-Specific Languages for Java
Xbase - Implementing Domain-Specific Languages for Javameysholdt
 
Java tutorial for Beginners and Entry Level
Java tutorial for Beginners and Entry LevelJava tutorial for Beginners and Entry Level
Java tutorial for Beginners and Entry LevelRamrao Desai
 
An Introduction to Scala for Java Developers
An Introduction to Scala for Java DevelopersAn Introduction to Scala for Java Developers
An Introduction to Scala for Java DevelopersMiles Sabin
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
First fare 2011 frc-java-introduction
First fare 2011 frc-java-introductionFirst fare 2011 frc-java-introduction
First fare 2011 frc-java-introductionOregon FIRST Robotics
 
openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animati...
openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animati...openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animati...
openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animati...roxlu
 
Chapter 01 Introduction to Java by Tushar B Kute
Chapter 01 Introduction to Java by Tushar B KuteChapter 01 Introduction to Java by Tushar B Kute
Chapter 01 Introduction to Java by Tushar B KuteTushar B Kute
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAMaulik Borsaniya
 
Ruby data types and objects
Ruby   data types and objectsRuby   data types and objects
Ruby data types and objectsHarkamal Singh
 
Java core - Detailed Overview
Java  core - Detailed OverviewJava  core - Detailed Overview
Java core - Detailed OverviewBuddha Tree
 

What's hot (20)

Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To Scala
 
Class 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented ProgrammingClass 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented Programming
 
Inheritance Mixins & Traits
Inheritance Mixins & TraitsInheritance Mixins & Traits
Inheritance Mixins & Traits
 
camel-scala.pdf
camel-scala.pdfcamel-scala.pdf
camel-scala.pdf
 
Xbase - Implementing Domain-Specific Languages for Java
Xbase - Implementing Domain-Specific Languages for JavaXbase - Implementing Domain-Specific Languages for Java
Xbase - Implementing Domain-Specific Languages for Java
 
Java tutorial for Beginners and Entry Level
Java tutorial for Beginners and Entry LevelJava tutorial for Beginners and Entry Level
Java tutorial for Beginners and Entry Level
 
An Introduction to Scala for Java Developers
An Introduction to Scala for Java DevelopersAn Introduction to Scala for Java Developers
An Introduction to Scala for Java Developers
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
Java Basics
Java BasicsJava Basics
Java Basics
 
First fare 2011 frc-java-introduction
First fare 2011 frc-java-introductionFirst fare 2011 frc-java-introduction
First fare 2011 frc-java-introduction
 
openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animati...
openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animati...openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animati...
openFrameworks freakDay S03E02 Diederick Huijbers - C++/Physics/Cloth Animati...
 
Chapter 01 Introduction to Java by Tushar B Kute
Chapter 01 Introduction to Java by Tushar B KuteChapter 01 Introduction to Java by Tushar B Kute
Chapter 01 Introduction to Java by Tushar B Kute
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
Scala Intro
Scala IntroScala Intro
Scala Intro
 
OOP in PHP
OOP in PHPOOP in PHP
OOP in PHP
 
Java
JavaJava
Java
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
 
Ruby data types and objects
Ruby   data types and objectsRuby   data types and objects
Ruby data types and objects
 
Chapter 05 classes and objects
Chapter 05 classes and objectsChapter 05 classes and objects
Chapter 05 classes and objects
 
Java core - Detailed Overview
Java  core - Detailed OverviewJava  core - Detailed Overview
Java core - Detailed Overview
 

Viewers also liked

Advanced System-Wide Performance Optimization of Ruby on Rails Applications
Advanced System-Wide Performance Optimization of Ruby on Rails ApplicationsAdvanced System-Wide Performance Optimization of Ruby on Rails Applications
Advanced System-Wide Performance Optimization of Ruby on Rails ApplicationsGonçalo Silva
 
SQL Server Lecture 1
SQL Server Lecture 1SQL Server Lecture 1
SQL Server Lecture 1Hazem Torab
 
Scaling Rails: a system-wide approach to performance optimization
Scaling Rails: a system-wide approach to performance optimizationScaling Rails: a system-wide approach to performance optimization
Scaling Rails: a system-wide approach to performance optimizationGonçalo Silva
 
Introduction to SQL Server Internals: How to Think Like the Engine
Introduction to SQL Server Internals: How to Think Like the EngineIntroduction to SQL Server Internals: How to Think Like the Engine
Introduction to SQL Server Internals: How to Think Like the EngineBrent Ozar
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerLuminary Labs
 

Viewers also liked (6)

Advanced System-Wide Performance Optimization of Ruby on Rails Applications
Advanced System-Wide Performance Optimization of Ruby on Rails ApplicationsAdvanced System-Wide Performance Optimization of Ruby on Rails Applications
Advanced System-Wide Performance Optimization of Ruby on Rails Applications
 
Scaling rails
Scaling railsScaling rails
Scaling rails
 
SQL Server Lecture 1
SQL Server Lecture 1SQL Server Lecture 1
SQL Server Lecture 1
 
Scaling Rails: a system-wide approach to performance optimization
Scaling Rails: a system-wide approach to performance optimizationScaling Rails: a system-wide approach to performance optimization
Scaling Rails: a system-wide approach to performance optimization
 
Introduction to SQL Server Internals: How to Think Like the Engine
Introduction to SQL Server Internals: How to Think Like the EngineIntroduction to SQL Server Internals: How to Think Like the Engine
Introduction to SQL Server Internals: How to Think Like the Engine
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI Explainer
 

Similar to Ruby — An introduction

Ruby :: Training 1
Ruby :: Training 1Ruby :: Training 1
Ruby :: Training 1Pavel Tyk
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n2
name name2 n2name name2 n2
name name2 n2callroom
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.pptcallroom
 
Ruby for Perl Programmers
Ruby for Perl ProgrammersRuby for Perl Programmers
Ruby for Perl Programmersamiable_indian
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# DevelopersCory Foy
 
Code for Startup MVP (Ruby on Rails) Session 2
Code for Startup MVP (Ruby on Rails) Session 2Code for Startup MVP (Ruby on Rails) Session 2
Code for Startup MVP (Ruby on Rails) Session 2Henry S
 

Similar to Ruby — An introduction (20)

Ruby :: Training 1
Ruby :: Training 1Ruby :: Training 1
Ruby :: Training 1
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Ruby Basics
Ruby BasicsRuby Basics
Ruby Basics
 
ppt7
ppt7ppt7
ppt7
 
ppt2
ppt2ppt2
ppt2
 
name name2 n
name name2 nname name2 n
name name2 n
 
name name2 n2
name name2 n2name name2 n2
name name2 n2
 
test ppt
test ppttest ppt
test ppt
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt21
ppt21ppt21
ppt21
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt17
ppt17ppt17
ppt17
 
ppt30
ppt30ppt30
ppt30
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.ppt
 
ppt18
ppt18ppt18
ppt18
 
Ruby for Perl Programmers
Ruby for Perl ProgrammersRuby for Perl Programmers
Ruby for Perl Programmers
 
ppt9
ppt9ppt9
ppt9
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# Developers
 
Code for Startup MVP (Ruby on Rails) Session 2
Code for Startup MVP (Ruby on Rails) Session 2Code for Startup MVP (Ruby on Rails) Session 2
Code for Startup MVP (Ruby on Rails) Session 2
 
Ruby
RubyRuby
Ruby
 

Recently uploaded

The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 

Recently uploaded (20)

The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 

Ruby — An introduction

  • 1. Ruby An introduction to the Ruby programming language LPOO — MIEIC — FEUP May 2011
  • 3. Ruby Created by Yukihiru “Matz” Matsumoto, in Japan Perl + SmallTalk + Eiffel + Ada + Lisp = Ruby “I wanted a scripting language that was more powerful than Perl, and more object-oriented than Python.” — matz
  • 4. Ruby Interpreted language, with many implementations: YARV , Rubinius , JRuby , etc Functional, object-oriented, imperative and reflective Dynamically typed, with automatic garbage collection, exception handling and built-in unit testing Optimized for programmer productivity and happiness
  • 6. Methods def hello_world() return "Hello world!" end hello_world()
  • 7. Methods def hello_world # no need for () "Hello world!" # implicit return end hello_world # no need for ()
  • 8. Classes class HelloWorld def say "Hello world done right!" end end hello_world_object = HelloWorld.new hello_world_object.say
  • 9. It's object-oriented class Lecture def initialize(name = "TBA", duration_in_minutes = 60) @name = name @duration = duration_in_minutes/60.0; end def description "Name: #{@name}nDuration: #{@duration} hours" end end lecture = Lecture.new("Ruby", 45) lecture.description
  • 10. It's really object-oriented // Java maximum = Math.max(1, 3) # Ruby maximum = [1, 3].max
  • 11. It's really object-oriented # Python positive = abs(num) # Ruby positive = num.abs
  • 12. It's really object-oriented // C length = strlen(name) # Ruby length = name.length
  • 13. It's really object-oriented In Ruby, all functions and most operators are methods of an object In Python, for instance, some functions are procedural Classes themselves are instances of Class
  • 14. It's really object-oriented Ruby has a permanent notion of the current object : self self controls how Ruby accesses instance variables All method calls are made on some object, called the receiver If no receiver is specified, self is used — it is implicit!
  • 15. It's really object-oriented # self is "main", an instance of Object class MyClass # self is MyClass def my_method # self will depend on the receiver for this method end end # self is "main" again, so my_object exists in the main scope my_object = MyClass.new # explicit receiver, so self will be my_object inside my_method my_object.my_method
  • 16. Arrays Store indexed collections of objects accessible through an integer key Can contain objects with different classes simultaneously # array a = [1, "second", 3.14] a[2]
  • 17. Hashes Store indexed collections of objects accessible through a key which can be any object Slightly less efficient but much more flexible # hash h = { "string" => [3,4,5], 2 => "everything can be a value!", [1,2] => "everything can be a key!" } h[[1,2]]
  • 18. Symbols A significant name, generally a static variable // java static final int NORTH = 1; // ... more code move(NORTH); # ruby move(:north) No need to predeclare these constants, they are unique return true if direction == :north
  • 19. Control Structures # if if score.between?(100, 199) puts "You rock!" elsif score < 50 puts "You suck!" else puts "Meh" end # while while score < 100 puts "You're almost there! Try again..." # ... end # more goodness with unless, until, case, for, etc # and awesome shortcuts like statement modifiers puts "You cheated!" if score >= 200
  • 21. Blocks A chuck of code enclosed between { } or do/end keywords Similar to the concept of anonymous methods Can take parameters Can be passed to methods as arguments (at the end, like an extra parameter) sum = 0 (1..5).each do |n| # same as [1,2,3,4,5] sum += n end sum # same thing with { } sum = 0 (1..5).each { |n| sum += n } sum
  • 22. Blocks as Objects Can be converted into objects Can be stored in variables, pass them around, invoke them whenever you want Great for implementing callbacks, dispatch tables, etc class BlockAsObject def store_block(&my_block) @stored_block = my_block # converted to Proc end def use_block(parameter) @stored_block.call(parameter) end end foo = BlockAsObject.new foo.store_block { |param| "The block was called with " + param } foo.use_block("delay")
  • 23. Blocks as Closures They can use local variables from the surrounding scope def powers_of_2_proc value = 1 lambda { value += value } end powers_of_2 = powers_of_2_proc powers_of_2.call # 2 powers_of_2.call # 4 powers_of_2.call # will return 8! So, powers_of_2_proc returns a Proc that references value When the block is called, value is out of scope The block is still able to access it (and will be for the remaining life of this block)
  • 24. Iterators In many languages, collections implement methods to generate external iterator objects // C++ for (std::vector<int>::iterator i=list.begin(); i!=list.end(); i++) { // code }
  • 25. Iterators In many languages, collections implement methods to generate external iterator objects // C# IEnumerator<int> i = list.GetEnumerator(); while (i.MoveNext()) { // code }
  • 26. Iterators In many languages, collections implement methods to generate external iterator objects // Java Iterator i = list.iterator(); while (i.hasNext()) { // code }
  • 27. Iterators When coming from other languages, many people iterate collections like this: # familiar? for i in 0..2 number = array[i][0] word = array[i][1] puts "#{word}: #{number}" end
  • 28. Iterators However, there's another approach: # the "ruby way", with a lot less coupling array.each do |word, number| puts "#{word}: #{number}" end The “Ruby way” is different: an iterator is internal to the collection... it's just a method that calls yield every time it generates a new value
  • 29. Iterators Ruby provides a lot of useful iterators: each, map , inject , etc But you can build your own def fib(max) i1, i2 = 1, 1 # parallel assignment while i1 <= max yield i1 i1, i2 = i2, i1+i2 end end result = "" fib(1337) { |n| result += "#{n} " } result
  • 30. Iterators Ruby's internal iterators aren't necessarily the best solution What if you need the iterator to be an object? What if you want to iterate multiple collections simultaneously?
  • 31. Enumerators When iterators aren't suitable, you can resort to enumerators To put it simply, an enumerator is an external iterator array = ["my", 1337, "array"] enumerator = array.to_enum # same as "enumerator = array.each" enumerator.next # returns "my" and moves to the next element enumerator.next
  • 32. Enumerators Most internal iterators are can be used as enumerators string = "le fu" enumerator = string.each_char enumerator.next # returns "l" and moves to the next char enumerator.next # returns "e" and moves to the next char
  • 33. Containers, containers, containers! Blocks and iterators are core concepts of Ruby With practice, you'll start building classes that iterate over their contents instead of using the conventional looping constructs It might seem complicated at first, but you'll start using these features naturally Easy to read and maintain
  • 35. Inheritance class SuperClass def hello_world "Hello world!" end end class SubClass < SuperClass end superclass = SuperClass.new subclass = SubClass.new "Hello world from the superclass: #{superclass.hello_world}n" + "Hello world from the subclass : #{subclass.hello_world}"
  • 36. Inheritance Single inheritance, unlike C++ Top-level classes are subclasses of Object , which is a subclass of BasicObject Classes have built-in functionality because they inherited it!
  • 37. Modules Modules provide a namespace, avoiding name collisions module MyModule # a module has it all MY_CONSTANT = "my constant" # constants def my_method # methods end class MyClass # and classes end end namespaced = MyModule::MyClass.new Modules have another wonderful use: mixins
  • 38. Mixins and Inheritance Some OO languages support multiple inheritance (C++, Lisp, Python, etc) This is very powerful, but can be troublesome because of inheritance ambiguity Ruby offers a great compromise: the simplicity of single inheritance and the power of multiple inheritance
  • 39. Mixins include is used to mix modules into classes or other modules module ToBeIncluded def foo "bar" end end class MyClass include ToBeIncluded end object = MyClass.new object.foo
  • 40. Mixins extend is used to add instance methods to a given object module ToBeIncluded def foo "bar" end end class MyClass end object = MyClass.new object.extend ToBeIncluded object.foo
  • 41. Mixins extend is also used to mix instance methods into a class module ToBeIncluded def foo "bar" end end class MyClass extend ToBeIncluded end MyClass.foo
  • 42. Mixins module StringHelpers class Over9000Number < Number def stringify include StringHelpers if self.value > 9000 "Over 9000!" def initialize(value) else super(value + 9000) "Meh" end end end def status end "Current status: "+stringify end class Number end attr_reader :value number = Over9000Number.new(42) def initialize(value) number.status @value = value # => "Current status: Over 9000!" end end Inherit from one class, include functionality from multiple modules — mixins !
  • 43. Inheritance, Mixins and Design Ruby allows you to right code once and inject it into multiple places When to use each? Inheritance You should be able to replace a parent object with a child object, honoring its contract A child object is a kind of the parent (an apple is a fruit) In the real world, strict hierarchies are restrictive... we need composition! Mixins For composition: A has a B, or A uses a B Exclusively using mixins can be messy — both should be combined
  • 44. Inheritance, Mixis and Design Each of them serves its purpose, our job is to use the appropriately None of these make any sense: class Person < DataWrapper end class Banana include FruitProperties end Think before you type
  • 46. Reflection Ruby is very powerful when it comes to examining the aspects of a program within itself It can discover information about: What objects exist All class hierarchies Attributes and methods of all objects Information about methods “When you introspect, you think about your thoughts and feelings. This is interesting because you're using thought to analyze thought.” — Dave Thomas
  • 47. Reflection and Objects You can transverse all living objects: ObjectSpace.each_object(Float) { |x| puts x }
  • 48. Reflection and Objects You can look inside objects: [1,2,3].methods[0..4] [1,2,3].respond_to?(:to_s) [1,2,3].kind_of?(Hash)
  • 49. Reflection and Objects You can invoke any method by name using send : a = [1,2,3] a.send(a.private_methods.first.to_sym) # "initialize" a # now it's empty!
  • 50. Reflection and Objects Another way is to use the Method class: a = [1,2,3] constructor = a.method(:initialize) constructor.call a You get a Method object which you can store, pass around and call anytime!
  • 51. Reflection and Classes It's also possible to look inside classes: String.ancestors # all superclasses and mixed-in modules
  • 52. Reflection and Classes It's also possible to look inside classes: klass = String result = klass.to_s begin klass = klass.superclass result += " < " + klass.to_s end while klass.superclass result
  • 53. Reflection and Classes It's also possible to look inside classes: Fixnum.constants Fixnum.class_variables Fixnum.singleton_methods(false) Fixnum.instance_methods(false) # private/protected/public prefix
  • 54. Reflection and the Program's Execution Ruby let's you look at the interpreter while it executes your code set_trace_func lambda { |event, file, line, id, binding, classname| printf "%8s %s:%s-2d %-15sn", event, file, line, classname, id } # all code is traced from now on And you can also get the current call stack by using calling caller on your methods
  • 55. Reflection and the Program's Execution You can even get the current source file being executed with the __FILE__ special variable, leading to an interesting Quine : print File.read(__FILE__) A program that outputs itself!
  • 57. Metaprogramming Ruby code can modify aspects of its own structure at runtime and it makes it all easy You've seen it before on this presentation: remember include and extend? Ruby is effectively injecting their code into their receiver
  • 58. Singleton Methods Ruby lets you define methods specific to a particular object person = "person" # String object def person.say_hi "Hi!" end person.say_hi Magic? No. Ruby created an anonymous class (often called singleton class) based on String and added the method say_hi to it
  • 59. Singleton Class There are other ways of creating methods in an object's singleton class person = "person" class << person def say_hi "Hi there!" end end person.say_hi
  • 60. Inherited Visibility The visibility of an inherited method can be changed class SuperClass private def my_private_method "U can't touch this" end end class SubClass < SuperClass public :my_private_method end object = SubClass.new object.my_private_method # not so private anymore
  • 61. Inherited Visibility What's really happening is that Ruby is inserting a hidden proxy method in the subclass that invokes the original method with super class SubClass < SuperClass def my_private_method super end public :my_private_method end super calls can access the parent's method regardless of its visibility
  • 62. Defining Methods Ruby allows you to define methods at runtime using define_method class BabyInfo ["cry", "eat", "poop"].each do |baby_action| define_method(baby_action) do "Of course, babies #{baby_action}" end end end baby_info = BabyInfo.new baby_info.cry Methods can also be blocked/removed by calling undef_method and remove_method, respectively
  • 63. Class-level Macros Ruby has a few class-level macros that generate code behind the scenes class Laptop attr_accessor :memory # injects a getter/setter for "memory" end If you've used Ruby on Rails, you've probably dealt with associations class Post < ActiveRecord::Base has_many :comments end
  • 64. Eval Similarly to other languages, eval evaluates the passed Ruby expression(s) course = "LPOO" eval "'Hello ' + course + '!'"
  • 65. Instance eval instance_eval allows you to evaluate Ruby expression(s) in the context of an instance string = "cool man cool" string.instance_eval "def shout; self.upcase; end" string.shout Remember: classes are instances of Class, so you can also use instance_eval with them: Fixnum.instance_eval "def ten; 10; end" Fixnum.ten
  • 66. Class eval As the name implies, class_eval can only be used with classes It evaluates the code as if you were in the context of the class definition String.class_eval do def shout self.upcase end end string = "cool man cool" string.shout Note: eval, instance_eval and class_eval can take blocks as arguments as shown above
  • 67. Eval evilness eval is slow eval is dangerous eval doesn't generally make sense, given all other metaprogramming facilities
  • 68. Callbacks Ruby provides hook methods , called by the interpreter when a specific event occurs Among all available hook methods —also known as callbacks —are: Method-related hooks: method_added, method_missing, method_removed, etc Class/Module-related hooks: const_missing, extended, included, inherited, etc Object marshaling and coercion hooks
  • 69. Callbacks: method_missing Ruby allows you to act upon calls to undefined methods by using method missing class BabyInfo ["cry", "eat", "poop"].each do |baby_action| define_method(baby_action) do "Of course, babies #{baby_action}" end end def method_missing(name, *args, &block) "Nope, babies don't #{name}" end end baby_info = BabyInfo.new baby_info.surf
  • 70. Callbacks: inherited Ruby allows your classes to act when they're subclassed class SuperClass @children = [] # class variable def self.inherited(child) @children << child end def self.children @children end end
  • 71. Callback: method calls Ruby allows you to intercept calls to specific methods: class Object alias_method :old_to_s, :to_s def to_s result = self.old_to_s "Your modified to_s returned this (should be '"+result+"')" end end object = Object.new object.to_s This isn't a direct hook: you're copying the original method and inserting a hook by yourself
  • 73. Ruby Ruby is an incredibly powerful language Many successful projects/products use it at their core: Ruby on Rails, God, Redmine, etc You can add and remove code in a running process, redefine methods on the fly, change their scope You can even modify basic types like String, Float or even Class and Object After using it for a while, you'll notice the lack of flexibility on static languages like C++ or half-static languages like Java
  • 74. Ruby This presentation, for instance, is running on a Sinatra application And most of the shown code was executed in real time No? Then check this out: class Lecture def initialize(name = "TBA") @name = name end def finish "Finished at #{(Time.now.utc+3600).strftime('%H:%M:%S')}!" end end lecture = Lecture.new("Ruby") lecture.finish
  • 75. More Books: Programming Ruby 1.9 by Dave Thomas Metaprogramming Ruby by Paolo Perrotta Mailing lists: Ruby-Talk (subscribe through Ruby's website) Ruby-pt (Google Groups) IRC: #ruby and #ruby-pt on Freenode
  • 76. ?