Transcript ruby1

A quick Ruby Tutorial
COMP313
Source: Programming Ruby, The Pragmatic
Programmers’ Guide by Dave Thomas, Chad
Fowler, and Andy Hunt
Ruby
•
•
•
•
Invented by Yukihiro Matsumoto, “Matz”
1995
Fully object-oriented
alternative to Perl or Python
How to run
• Command line: ruby <file>
• Interactive: irb
• Resources:
– see web page
– man ruby
Simple method example
def sum (n1, n2)
n1 + n2
end
sum( 3 , 4) => 7
sum(“cat”, “dog”) => “catdog”
load “fact.rb”
fact(10) => 3628800
executable shell script
#!/usr/bin/ruby
print “hello world\n”
or better: #!/usr/bin/env ruby
make file executable: chmod +x file.rb
Method calls
"gin joint".length → 9
"Rick".index("c") → 2
-1942.abs → 1942
Strings: ‘as\n’ => “as\\n”
x=3
y = “x is #{x}” => “x is 3”
Another method definition
def say_goodnight(name)
"Good night, #{name}"
end
puts say_goodnight('Ma')
produces: Good night, Ma
Name conventions/rules
• local var: start with lowercase or _
• global var: start with $
• instance var: start with @
• class var: start with @@
• class names, constant: start uppercase
following: any letter/digit/_ multiwords
either _ (instance) or mixed case
(class), methods may end in ?,!,=
Naming examples
•
•
•
•
•
local: name, fish_and_chips, _26
global: $debug, $_, $plan9
instance: @name, @point_1
class: @@total, @@SINGLE,
constant/class: PI, MyClass,
FeetPerMile
Arrays and Hashes
• indexed collections, grow as needed
• array: index/key is 0-based integer
• hash: index/key is any object
a = [ 1, 2, “3”, “hello”]
a[0] => 1
a[2] => “3”
a[5] => nil (ala null in Java, but proper Object)
a[6] = 1
a => [1, 2, “3”, “hello”, nil, nil, 1]
Hash examples
inst = { “a” => 1, “b” => 2 }
inst[“a”] => 1
inst[“c”] => nil
inst = Hash.new(0) #explicit new with default 0
instead of nil for empty slots
inst[“a”] => 0
inst[“a”] += 1
inst[“a”] => 1
Control: if example
if count > 10
puts "Try again"
elsif tries == 3
puts "You lose"
else
puts "Enter a number"
end
Control: while example
while weight < 100 and num_pallets <= 30
pallet = next_pallet()
weight += pallet.weight
num_pallets += 1
end
nil is treated as false
while line = gets
puts line.downcase
end
Statement modifiers
• useful for single statement if or while
• similar to Perl
• statement followed by condition:
puts "Danger" if radiation > 3000
square = 2
square = square*square while square < 1000
builtin support for Regular
expressions
/Perl|Python/ matches Perl or Python
/ab*c/ matches one a, zero or more bs and
one c
/ab+c/ matches one a, one or more bs and
one c
/\s/ matches any white space
/\d/ matches any digit
/\w/ characters in typical words
/./ any character
(more later)
more on regexps
if line =~ /Perl|Python/
puts "Scripting language mentioned: #{line}"
end
line.sub(/Perl/, 'Ruby') # replace first 'Perl' with 'Ruby'
line.gsub(/Python/, 'Ruby') # replace every 'Python' with 'Ruby’
# replace all occurances of both ‘Perl’ and ‘Python’ with ‘Ruby’
line.gsub(/Perl|Python/, 'Ruby')
Code blocks and yield
def call_block
puts "Start of method"
yield
yield
puts "End of method"
end
call_block { puts "In the block" }
Start of method
In the block
In the block
End of method
produces:
parameters for yield
def call_block
yield("hello",2)
end
then
call_block { | s, n | puts s*n, "\n" }
hellohello
prints
Code blocks for iteration
animals = %w( ant bee cat dog elk ) # create an array
# shortcut for animals = {“ant”,”bee”,”cat”,”dog”,”elk”}
animals.each {|animal| puts animal } # iterate
produces:
ant
bee
cat
dog
elk
Implement “each” with “yield”
# within class Array...
def each
for every element # <-- not valid Ruby
yield(element)
end
end
More iterations
[ 'cat', 'dog', 'horse' ].each {|name| print name, "
"}
5.times { print "*" }
3.upto(6) {|i| print i }
('a'..'e').each {|char| print char }
[1,2,3].find { |x| x > 1}
(1...10).find_all { |x| x < 3}
I/O
• puts and print, and C-like printf:
printf("Number: %5.2f,\nString: %s\n", 1.23,
"hello")
#produces:
Number: 1.23,
String: hello
#input
line = gets
print line
leaving the Perl legacy behind
while gets
if /Ruby/
print
end
end
ARGF.each {|line| print line if line =~ /Ruby/ }
print ARGF.grep(/Ruby/)
Classes
class Song
def initialize(name, artist, duration)
@name = name
@artist = artist
@duration = duration
end
end
song = Song.new("Bicylops", "Fleck", 260)
override to_s
s.to_s => "#<Song:0x2282d0>"
class Song
def to_s
"Song: #@name--#@artist (#@duration)"
end
end
s.to_s => "Song: Bicylops--Fleck (260 )”
Some subclass
class KaraokeSong < Song
def initialize(name, artist, duration, lyrics)
super(name, artist, duration)
@lyrics = lyrics
end
end
song = KaraokeSong.new("My Way", "Sinatra",
225, "And now, the...")
song.to_s → "Song: My Way--Sinatra (225)"
supply to_s for subclass
class KaraokeSong < Song
# Format as a string by appending lyrics to parent's to_s value.
def to_s
super + " [#@lyrics]"
end
end
song.to_s → "Song: My Way--Sinatra (225) [And now, the...]"
Accessors
class Song
def name
@name
end
end
s.name => “My Way”
# simpler way to achieve the same
class Song
attr_reader :name, :artist, :duration
end