CS152-Day16-Ruby-(condensed)condensed).pdf · 2018-07-30 · Ruby. Introduction to Ruby Created by...

Post on 14-May-2020

9 views 0 download

Transcript of CS152-Day16-Ruby-(condensed)condensed).pdf · 2018-07-30 · Ruby. Introduction to Ruby Created by...

http://ars.userfriendly.org/cartoons/?id=20080627

Review Prolog Lab

Review Project, part 3

CS 152: Programming Language Paradigms

Prof. Tom AustinSan José State University

Ruby

Introduction to Ruby

Created byYukihiro Matsumoto(known as "Matz")

Ruby influences

Smalltalk• everything is an object• blocks• metaprogramming

Perl• regular expressions• function names

Ruby on Rails

• Ruby's "killer app"–lightweight web framework–"convention over configuration"

• David Heinemeier Hansson (DHH)–initial framework was PHP–abandoned PHP for Ruby

Hello World in Ruby

puts 'Hello world!'

Working with data structures

a = [1,2,3]m = {'a'=>"Apple",

'b'=>"Banana",'c'=>"Cantalope"}

puts a[0]puts m['a']

Ruby is object-oriented

"I was talking with my colleague about the possibility of an object-oriented scripting language. […] I knew Python then. But I didn't like it, because I didn't think it was a true object-oriented language — OO features appeared to be add-on to the language. As a language maniac and OO fan for 15 years, I really wanted a genuine object-oriented, easy-to-use scripting language. I looked for but couldn't find one. So I decided to make it." --Matz 1999

class Persondef initialize name # Constructor

@name = nameend

def name # Getterreturn @name

end

def name= newName # Setter@name = newName

end

def say_hi # Methodputs "Hello, my name is #{@name}."

endend

The @ indicates an object's field

The = in the method name (by convention) indicates assignment

Generating getters and setters

class Personattr_accessor :name def initialize name # Constructor@name = name

enddef say_hi # Methodputs "Hello, my name is #{@name}."

endend

Powerful metaprogramming

Using a class in Ruby

p = Person.new "Joe"puts "Name is #{p.name}"p.say_hi

Inheritance in Ruby(in-class)

Mixins

• Allow user to add features to a class• Similar to interfaces in Java, but

programmer can specify functionality. class Person

include Comparableend

module RevStringdef to_rev_sto_s.reverse

endend

class Person # Re-opening classinclude RevStringdef to_s@name

endend

p.to_rev_s # p defined previously

Dynamic code evaluation

eval• Executes dynamically• Typically, eval takes a string:eval "puts 2+3"• Popular feature–especially in JavaScript• Richards et al. The Eval that Men Do, 2011

• Source of security problems

Additional Ruby eval methods

• instance_eval–evaluates code within object body

• class_eval–evaluates code within class body

• Take a string or a block of code–block of code more secure

String Processing

Regular Expressions in Ruby

s = "Hi, I'm Larry; this is my" +" brother Darryl, and this" +" is my other brother Darryl."

s.sub(/Larry/,'Laurent')puts ss.sub!(/Larry/,'Laurent')puts sputs s.sub(/brother/, 'frère')puts s.gsub(/brother/, 'frère')

Regular Expression Symbols• /./ - Any character except a newline• /\w/ - A word character ([a-zA-Z0-9_])• /\W/ - A non-word character ([^a-zA-Z0-9_])• /\d/ - A digit character ([0-9])• /\D/ - A non-digit character ([^0-9])• /\s/ - A whitespace character: /[ \t\r\n\f]/• /\S/ - A non-whitespace char: /[^ \t\r\n\f]/• * - Zero or more times• + - One or more times• ? - Zero or one times (optional)

References for Ruby

• "Programming Ruby: The Pragmatic Programmer's Guide", http://ruby-doc.com/docs/ProgrammingRuby/• "Why's Guide to Ruby",

http://mislav.uniqpath.com/poignant-guide/ (unusual, but entertaining reference).• David Black, "Ruby for Rails",

2006.

Lab: Eliza in Ruby

Use Ruby to model a psychiatrist.http://en.wikipedia.org/wiki/ELIZA

Download eliza.rb from the course website and extend it. Note that if you call `ruby eliza.rb -test`, you will get some cases to consider.

Smalltalk influences on Ruby

•Everything is an object•Blocks•Message passing

BlocksBlocks

file = File.open('temp.txt', 'r')

file.each_line do |line|puts line

endfile.close

File I/O

File.open('file','r') do |f|f.each_line { |ln| puts ln }

end

File I/O with blocks

Ruby methods can accept blocks to• create custom

control structures• eliminate

boilerplate code

Creating custom blocks

with_prob• Accepts:–a probability (between 0 and 1)–a block

• Executes block probabilistically–with_prob 0 { puts "hi" }–with_prob 1 { puts "hi" }–with_prob 0.5 { puts "hi" }

def with_prob (prob)yield if (Random.rand < prob)

end

with_prob 0.42 doputs "There is a 42% chance "

+ "that this code will print"end

Single-line ifstatements come

after the body

def with_prob (prob, &blk)blk.call if (Random.rand < prob)

end

with_prob 0.42 doputs "There is a 42% chance "

+ "that this code will print"end

We can explicitly name the block of code

Note that there is no '&' here.

def with_prob (prob, &blk)blk.call if (Random.rand < prob)

end

def half_the_time (&block)with_prob(0.5, &block)

endExplicitly naming

the block is useful if we wish to pass it to

another method

Conversion table example(in class)

Blocks are closures, though there are some differences between JavaScript functions and Ruby blocks.

Let's see how the two compare…

Writing withProb in JavaScript

function withProb(prob, f) {if (Math.random() < prob) {

return f();}

}JavaScript uses callbacks rather

than blocks

What is the difference?

def coin_flipwith_prob 0.5do

return "H"endreturn "T"

end

function coinFlip() {withProb(0.5,

function() {return "H";

});return "T";

}

Singleton classes

JavaScript & prototypesfunction Employee(name, salary) {

this.name = name;this.salary = salary;

}var a = new Employee("Alice", 75000);var b = new Employee("Bob", 50000);

b.signingBonus = 2000;console.log(a.signingBonus);console.log(b.signingBonus);

Can we do the same thing in

Ruby?

In Ruby, every object has a special singleton class.

This class holds methodsunique to that object.

Singleton Class Example(in-class)

Message Passing

Message passing (object interaction)

• Sender sends–message: method name–data: method parameters

• Receiver–processes the message–(optionally) returns data

If receiver doesn't understand message?irb> "hello".fooNoMethodError: undefined method `foo' for "hello":String

from (irb):2from /usr/bin/irb:12:in

`<main>'irb>

method_missing

• You can override this behavior–Smalltalk: doesNotUnderstand–Ruby: method_missing

• This method is called when an unknown method is invoked

class Personattr_accessor :namedef initialize(name)

@name = nameenddef method_missing(m)

puts "Didn't understand #{m}"end

end

bob = Person.new "Robert"class << bob

def method_missing mphrase = m.to_s.sub(

/say_(.*)/, '\1')puts phrase

endend

Rails ActiveRecord example

Person.find_by(first_name: 'David')

Person.find_by_first_name "John"

Person.find_by_first_name_and_last_name \"John", "Doe"

Record example(in class)