A quick Ruby Tutorial, Part 2

30
A quick Ruby Tutorial, Part 2 COMP313 Source: Programming Ruby, The Pragmatic Programmers’ Guide by Dave Thomas, Chad Fowler, and Andy Hunt

description

A quick Ruby Tutorial, Part 2. COMP313 Source: Programming Ruby, The Pragmatic Programmers’ Guide by Dave Thomas, Chad Fowler, and Andy Hunt. Writing attributes. class Song def duration=(new_duration) @duration = new_duration end end song = Song.new("Bicylops", "Fleck", 260) - PowerPoint PPT Presentation

Transcript of A quick Ruby Tutorial, Part 2

Page 1: A quick Ruby Tutorial, Part 2

A quick Ruby Tutorial, Part 2

COMP313

Source: Programming Ruby, The Pragmatic Programmers’ Guide by Dave Thomas, Chad

Fowler, and Andy Hunt

Page 2: A quick Ruby Tutorial, Part 2

class Song def

duration=(new_duration)

@duration = new_duration

end

end

song = Song.new("Bicylops", "Fleck", 260)

song.duration → 260

song.duration = 257 # set attribute with updated value

song.duration → 257

Writing attributes

Page 3: A quick Ruby Tutorial, Part 2

class Song

attr_writer :duration

end

song = Song.new("Bicylops", "Fleck", 260)

song.duration = 257

Simpler

Page 4: A quick Ruby Tutorial, Part 2

class Song def duration_in_minutes @duration/60.0 # force floating point end def duration_in_minutes=(new_duration) @duration = (new_duration*60).to_i end end song = Song.new("Bicylops", "Fleck", 260) song.duration_in_minutes → 4.33333333333333 song.duration_in_minutes = 4.2 song.duration → 252

Virtual attributes

Page 5: A quick Ruby Tutorial, Part 2

class Song @@plays = 0 def initialize(name, artist, duration) @name = name @artist = artist @duration = duration @plays = 0 end def play @plays += 1 @@plays += 1 "This song: #@plays plays. Total #@@plays plays." end end

Class variables

Page 6: A quick Ruby Tutorial, Part 2

class Example

def instance_method # instance method

end

def Example.class_method # class method

end

end #uses:Example.class_methodExample.new

Class methods

Page 7: A quick Ruby Tutorial, Part 2

class MyLogger

private_class_method :new

@@logger = nil

def MyLogger.create

@@logger = new unless @@logger

@@logger

end

end

Singleton class example

Page 8: A quick Ruby Tutorial, Part 2

• public: default for all methods (except initialize), accessible by everyone

• protected: access within class and all subclasses (!= Java)

• private: only the current object (again != Java)

• checked at runtime only!

Access control

Page 9: A quick Ruby Tutorial, Part 2

class MyClass def method1 # default is 'public' #... end protected # subsequent methods will be 'protected' def method2 # will be 'protected' #... end private # subsequent methods will be 'private' def method3 # will be 'private' #... end public # subsequent methods will be 'public' def method4 # and this will be 'public' #... end end

How to define access

Page 10: A quick Ruby Tutorial, Part 2

class MyClass

def method1

end

# ... and so on

public :method1, :method4

protected :method2

private :method3

end

Alternatively

Page 11: A quick Ruby Tutorial, Part 2

class Accounts def initialize(checking, savings) @checking = checking @savings = savings end private def debit(account, amount) account.balance -= amount end def credit(account, amount) account.balance += amount end public #... def transfer_to_savings(amount) debit(@checking, amount) credit(@savings, amount) end #... end

Account example

Page 12: A quick Ruby Tutorial, Part 2

class Account

attr_reader :balance # accessor method 'balance'

protected :balance # and make it protected

def greater_balance_than(other)

return @balance > other.balance

end

end

Protected example

Page 13: A quick Ruby Tutorial, Part 2

person1 = "Tim" person2 = person1 person1[0] = 'J' person1 → "Jim" person2 → "Jim”

person1 = "Tim" person2 = person1.dup person1[0] = "J" person1 → "Jim" person2 → "Tim"

Assignment semantics (like Java)

Page 14: A quick Ruby Tutorial, Part 2

person1 = "Tim"

person2 = person1

person1.freeze # prevent modifications to the object

person2[0] = "J" produces: prog.rb:4:in `[]=': can't modify frozen string (TypeError)

from prog.rb:4

“freeze” objects

Page 15: A quick Ruby Tutorial, Part 2

a = [ 1, 3, 5, 7, 9 ] a[-1] → 9 a[-2] → 7 a[-99] → nil a[1, 3] → [3, 5, 7] a[3, 1] → [7] a[-3, 2] → [5, 7] a[1..3] → [3, 5, 7] a[1...3] → [3, 5] a[3..3] → [7] a[-3..-1] → [5, 7, 9]

Array access (again)

Page 16: A quick Ruby Tutorial, Part 2

class SongList def initialize @songs = Array.new end def append(song) @songs.push(song) self end def delete_first @songs.shift end def delete_last @songs.pop end end

Implement own sample container

Page 17: A quick Ruby Tutorial, Part 2

class SongList

def [](index)

@songs[index]

end

end

Defining array-like access

Page 18: A quick Ruby Tutorial, Part 2

require 'test/unit' class TestSongList < Test::Unit::TestCase def test_delete list = SongList.new s1 = Song.new('title1', 'artist1', 1) s2 = Song.new('title2', 'artist2', 2) list.append(s1).append(s2) assert_equal(s1, list[0]) assert_equal(s2, list[1]) assert_nil(list[9]) assert_equal(s2, list.delete_last) assert_equal(s1, list.delete_first) assert_nil(list.delete_last) end end

Unit testing

Page 19: A quick Ruby Tutorial, Part 2

class SongList

def with_title(title)

for i in [email protected]

return @songs[i] if title == @songs[i].name

end

return nil

end

end

Finding songs by title

Page 20: A quick Ruby Tutorial, Part 2

class SongList

def with_title(title)

@songs.find {|song| title == song.name }

end

end

Finding songs by title (the Ruby way)

Page 21: A quick Ruby Tutorial, Part 2

class Array

def find

for i in 0...size

value = self[i]

return value if yield(value)

end

return nil

end

end

[1, 3, 5, 7, 9].find {|v| v*v > 30 } → 7

Hypothetical find in Array

Page 22: A quick Ruby Tutorial, Part 2

[1,3,5,7].inject(0) {|sum, element| sum+element} → 16

[1,3,5,7].inject(1) {|product, element| product*element} → 105

[1,3,5,7].inject {|sum, element| sum+element} → 16

[1,3,5,7].inject {|product, element| product*element} → 105

inject iterator

Page 23: A quick Ruby Tutorial, Part 2

• are “internal”, I.e. just another method

• Java et.al.: “external”, I.e. explicit additional object

• pros and cons

Iterators in Ruby

Page 24: A quick Ruby Tutorial, Part 2

class File

def File.my_open(*args)

result = file = File.new(*args)

# If there's a block, pass in the file and close it on returns

if block_given?

result = yield file

file.close

end

return result

end

end

more on code blocks

Page 25: A quick Ruby Tutorial, Part 2

def n_times(thing) return lambda {|n| thing * n } end

p1 = n_times(23) p1.call(3) → 69 p1.call(4) → 92

p2 = n_times("Hello ") p2.call(3) → "Hello Hello Hello "

proc and lambda

Page 26: A quick Ruby Tutorial, Part 2

• ints are either in -2^30 to 2^30-1 (or -2^62 to 2^62-1) or arbitrarily large BigNums

num = 81

6.times do

puts "#{num.class}: #{num}"

num *= num

end

Numbers

Page 27: A quick Ruby Tutorial, Part 2

3.times { print "X " }

1.upto(5) {|i| print i, " " }

99.downto(95) {|i| print i, " " }

50.step(80, 5) {|i| print i, " " }

Loops using numbers

Page 28: A quick Ruby Tutorial, Part 2

• 1.to_i or Integer(1)

some_file = File.new(“xyz”,”r”)

some_file.each { |line|

v1, v2 = line.split

print v1.to_i + v2.to_i, " ”

}

Strings to numbers

Page 29: A quick Ruby Tutorial, Part 2

/jazz/j00132.mp3 | 3:45 | Fats Waller | Ain't Misbehavin'

/jazz/j00319.mp3 | 2:58 | Louis Armstrong | Wonderful World

/bgrass/bg0732.mp3| 4:09 | Strength in Numbers | Texas Red

break lines into fieldsconvert runtime into secondsremove extra spaces in artists’ names

Song database

Page 30: A quick Ruby Tutorial, Part 2

File.open("songdata") do |song_file|

songs = SongList.new

song_file.each do |line|

file, length, name, title = line.chomp.split(/\s*\|\s*/)

name.squeeze(“ “)

mins, secs = length.scan(/\d+/)

songs.append(Song.new(title, name, mins.to_i*60+secs.to_i))

end

songs

end

Song database: code