Programming Languages

Scripting in Ruby

Jim Posen - ECE/CS 2014

Scripting Languages

  • Dynamic
  • High-level
  • Interpreted
  • Integration with operating system/environment

Examples

  • Bash
  • Perl
  • Python
  • Ruby
  • sed/awk
  • Tcl
  • JavaScript

Scripts

  • Easy to write
  • Quick automation
  • Don’t need to scale
  • Usually pretty hacky
  • Unix utilities

Bash

  • Remember our log parsing shell script?

Ruby

  • Ruby is multiparadigm
  • Originally designed as a scripting language with good object oriented principles
  • Dynamic/interpreted/strongly typed
  • Lots of syntactic sugar

Principles

  • Extremely flexible
  • “I wanted a scripting language that was more powerful than Perl, and more object-oriented than Python.
  • Ruby is supposed to make life better for programmers
  • Code to be read by humans, not machines
  • MINSWAN

Ruby History

  • 1993: Yukihiro Matsumoto (Matz) creates Ruby
  • 1995: Ruby is released to the world
  • 2005: David Heinemeier Hansson creates Ruby on Rails
  • 2006: Rails helps Ruby gain popularity
  • 2007: Why the Lucky Stiff creates GUI Toolkit Shoes

The State of Ruby

  • Ruby and Rails are wildly popular
  • Second most popular language on GitHub after JavaScript
  • Ruby 2.0 released earlier this year

Parts of Speech

  • Variables
  • Numbers
  • Strings
  • Symbols
  • Constants
  • Methods
  • Blocks
  • Ranges
  • Arrays
  • Hashes
  • Regular Expressions

Variables

  • Dynamically typed
  • Underscored by convention
  • Locally scoped
  • $var is a global
  • @var is an instance variable
  • @@var is a class variable

Number Literals

  • 10
  • 10.1
  • 1.1e5

Strings

  • Strings enclosed by single or double quotes
  • Can be multiline strings

String Interpolation

  • Double quotes interpolate
name = 'Dr. Nick'
puts "Hi #{name}"

Symbols

  • Lightweight strings
  • Preceded by colons
  • We saw them in Lisp
  • Used as identifiers
  • :left, :right, :up, :down

Constants

  • Must start with uppercase letter
  • All uppercase by convention
  • Ruby will warn you if a constant is reassigned

Nil

  • nil is like null in Java
  • It is an object of type NilClass
  • Interpreted as false in a conditional

Conditionals

  • if statements are our bread and butter conditional
  • Use elsif keyword for multiconditionals
  • As in Lisp and Haskell, if statements evaluate to a value
  • Evaluates to nil if there is no else and the condition is false
irb> if 2 > 3
irb>   puts "Hello"
irb> end
=> nil
irb> if 2 > 3
irb>   puts "Hello"
irb> else
irb>   puts "Goodbye"
irb>   "World"
irb> end
Goodbye
=> "World"

Method Invocation

  • Methods called with dot notation
  • Method arguments given with parenthesis
irb> 2.even?()
true
irb> "Hello World!".split(' ')
["Hello", "World!"]

Naming conventions

  • Method names are underscored
  • Boolean methods end in a ?
  • Dangerous/destructive methods end in a !
    • game.reset!

Poetry mode

  • Ruby methods do not need to be invoked with parenthesis
  • Use responsibly
  • When in doubt, use parenthesis
irb> 2.even?
true
irb> "Hello World!".split ' '
["Hello", "World!"]

Method Definition

  • def keyword used to define methods
  • Functions evaluate to the last statement
  • Return statement stops execution
def fib(n)
  if n < 2
    return n
  end
  fib(n - 1) + fib(n - 2)
end

Default arguments

def fib(n, x1 = 0, x2 = 1)
  return x1 if n == 0
  return x2 if n == 1
  fib(n - 1, x2, x1 + x2)
end

Keyword arguments

def method_with_options(takes_kittens: true, num_puppies: 3, max_puppy_size: 8)
    ...
end

Splats

  • Splats group undefined arguments into arrays and hashes
def method_with_splats(*args, **kwargs)
    ...
end

Methods vs Functions

  • Functions are operations that have inputs, outputs, and side effects
    • Everything we have seen up until now
  • Methods are named functions defined on objects
    • Used in object oriented programming
  • Often used interchangably, but there is a difference
  • Ruby has methods
    • In literature, this is called foreshadowing

Blocks

  • Code can be passed as a method argument
  • This is called a block
  • Use curly braces or do/end
  • Arguments (if any) go in |
10.times { |i| puts i }
10.times do |i|
  puts i
end

Accepting blocks

  • yield keyword to call to block argument
  • Alternately, explicitly accept a Proc argument
  • Use Proc#call to call a block
def times(n, &proc)
  return if n == 0
  proc.call n
  times(n - 1, &proc)
end

Lambdas

  • Create Procs explicitly with lambda
  • Arrow syntax for lambdas
irb> double = lambda { |x| x + x }
irb> double = ->(x) { x + x }
irb> double.call 2
4

Ranges

  • A range is an iterable structure
  • .. for inclusive range
  • … for exclusive range
irb> (0..2).each { |i| puts i }
0
1
2
irb> (0...2).each { |i| puts i }
0
1

Arrays

  • Not fixed size
  • They are like ArrayLists in Java
  • You can mix types
  • You can add arrays with +
  • You can add append to arrays with <<
irb> a = [1, 2, '3']
irb> a << 4
irb> a
[1, 2, '3', 4]
irb> a + [6, 7]
[1, 2, '3', 4, 6, 7]

Our favorite functions

  • map , filter , and reduce are defined on arrays
irb> [0..2].map { |x| x * 2 }
[0, 2, 4]
irb> [0..2].filter { |x| x.even? }
[0, 2]
irb> [0...3].reduce(0) { |sum, elt| sum + elt }
6

Iteration

  • We don’t use for loops in Ruby
  • The each method provides iteration
irb> ['cat', 'dog', 'mouse'].each { |animal| puts animal }
cat
dog
mouse

Hashes

  • Constant time lookup structure
  • Like HashMaps in Java
  • Fat arrows for key-value pairs
  • Colon syntax for symbol keys
irb> { 'puppy' => Dog, 'kitten' => Cat, 'cub' => Bear }
irb> { :puppy => Dog, :kitten => Cat, cub: Bear }
irb> h = { :puppy => Dog, kitten: Cat, cub => Bear }
irb> h[:puppy]
Dog
irb> h[:puppy] = Wolf
irb> h[:puppy]
Wolf

Iteration

  • Use each again
  • map , filter , and reduce are, of course, defined on hashes
irb> h.each { |key, value| ... }

Regular Expressions

  • A language for defining string patterns
  • Used in all languages
  • This is so ridiculously useful, I can’t stress it enough
  • Regexs are delimited by forward slashes
  • =~ operator performs matching
irb> "abc def" =~ /a.c/
0
irb> "def abc" =~ /a.c/
4
irb> "abc def" =~ /adc/
nil

Regex Syntax

  • Let’s test some out on Rubular
  • Most characters represent themselves
  • * means 0 or more of the preceding pattern
  • + means 1 or more of the preceding pattern
  • ? means 0 or 1 of the preceding pattern

Character Sets

  • [] is a character set
  • [bcd] is either b, c, or d
  • [a-z012] is any lowercase character or 0, 1, or 2
  • [^a] is any character that is NOT a

Special Characters

  • \d is a digit
  • \w is a letter, digit, or underscore
  • \s is a whitespace character
  • \S is a non-whitespace character