Intro to Ruby

For Sysads

Why Ruby?

  1. We are already using it in puppet
  2. It makes easy to reason about logic compared to bash
  3. Its fun.
  4. Its fast.
  5. Lots of online documentation.
  6. Functional Programming

Lets Quick Start With Values


"string"     #this is string, strings can be double or single quoted
1            #this is number
4.0          # this is float
true         #this is boolean
false        #the other boolean
nil          #another value, like boolean but not same
/regex/      #regexs are builtin and readily available
[1,2,3]      # arrays

#hash can have anything as key and value
{:a => "a", :b => "b", "c" => c }

More Values

#common expressions
true == false                  #=> false
false !=  true                 #=> true
"somestring" =~ /string$/      #=> true (as it matches)not 
not true                       #=> false
false or true                  #=> true
true and false                 #=> false

require "time"                 #this is how we import a library
puts "string"                  #print string
now =               #assign value
puts "current time is #{time}" #string interpolation


3.times do
  puts "something"

for i in 0..9 do
    puts "#{i}"

i = 0 ; while i < 10 do
    i = i + 1; puts i

i = 0; until i > 10 do 
    i = i + 1; puts i


array = ["this","is","an","array"]

# ugly way
for i in 0..array.length do
puts array[i]

# better way
array.each do |v|
puts v

hash = {:a => "a" , :b => "b"}
hash.each do |k,v|
puts k,v


# infinite loop, use with caution
loop do
print "Input: "
line = gets
break if !line or line =~ /^qQ/
end # generate valued loop, something like for (0..10).each do |v| next if v < 5 puts v end

Flow Control

x = 1

if x == 2
  puts "x is 2"
elsif x == 1
  puts "x is 1"
  puts "x is neither one 1 or 2"

y = 6 if x == 1               # we can use if in assignment statement

Flow Control

unless false                  # unless is short for if not
puts "this will run"

y = 7 unless defined? (y) #we can use unless in assignment statement # assign using if else block y = if someexpression() somefunction() else someotherfunction() end

Flow Control

test = somefunc()

case test
    when test.is_a? String
        puts "test is string"
    when test.is_a? FixNum
        puts "test is a integer"
    when test.is_a? Float
        puts "test is a floating point number"
        puts "can't identify what test is"


def func(arg1,arg2)
    arg1 + arg2      #last statement's value is returned

puts "val"                # print statement returns nil

def func2(arg1 ,arg 2,arg 3)
  puts,arg3)    # prints value but returns nil as puts ...
end                            # returns nil

func2(func,1,2)  #prints sum of arg2 and arg3, functions are first class

Ruby Fundamentals

Almost Everything in ruby is an object, lets examine using reflection api

3.class              #objects are instance of a class
3.methods            #objects have methods
3.class.class        #classes inherits Class class

3.class.ancestors    #classes have ancestors
3.is_a? Object       #objects are instance of object class
3.is_a? Class        #But instances of a class are not class

Class.is_a? Object   #class Class inherits Object class

3.send("abs")        #You can send methods to objects by creating strings 

Ruby Fundamentals..

Declaring class

class Someclass
  @@var1 = 0         #a class variable shared across different instances of class
  def initialize(v1) #initialize instance variable, different for each instance
    @v1 = v1
  def instancemethod(v2)    #instance method
    puts @v1 + v2       #v2 is a local variable for functino
  def self.classmethod(v3)
    @@var1 += v3
v = 1 ; v.instancemethod(5)

Ruby Fundamentals

Extend existing class

 class Hash
def inverse
self.reduce({}){ |h,(k,v)| (h[v] ||=[]) << k; h}
end k = {"a" => 1, "b" => 2, "c" => 1} k.inverse #=> {1 => ["a","c"],2 => "b"}

Calling external code

k = `ls -alh /home/`      # gives standard output as string
y = %x[ls -alh /home]     # does the same thing as above

$?.exitstatus             # will give exitcode of the last command ran
$?.pid                    #gives process id of last command ran

val = "/home/"

dirs = `ls #{val}`


Functional Programming

  • Makes program easy to reason about
  • Takes a little getting used to
  • Fast, concise logic
  • Higher order functions
  • Very useful when using ruby collections

Functional programming..

#Higher order function examples

$dates = (0..3){ |n| - 86400 * n }.map {|n| n.strftime "%d-%m-%Y"}

$hosts = Dir.entries("/data/hosts/").select {|v| v =~ /.net|.in/}

$hosts = Dir.entries("/data/hosts/").select {|v| v =~ /.net|.in/}.reject { |v| v =~ /bll-2/}

Useful Libraries

require 'time'      #for time related functions
require 'fileutils' #for file related functons

require 'optparse'  #to create cli parser 

require 'resolv'    #for dns related functions

require 'json'      #for json related functions
require 'yaml'      #for reading yaml files
require 'rexml'     #for xml parsing

require 'pp'        #for pretty printing, useful for debugging

Helpful tips

  • Use ri for offline help
  • Use rvm/rbenv for switching ruby version
  • irb is your friend, helps to quickly test
  • pry is another useful shell to
  • is helpful
  • Don't forget stack overflow
  • Google usually points in the right direction

Useful links


Intro to Ruby

By Ayush Goyal

Intro to Ruby

  • 1,032