Upload
others
View
11
Download
0
Embed Size (px)
Citation preview
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)