a quick ruby tutorial part 2
Download
Skip this Video
Download Presentation
A quick Ruby Tutorial, Part 2

Loading in 2 Seconds...

play fullscreen
1 / 30

A quick Ruby Tutorial, Part 2 - PowerPoint PPT Presentation


  • 137 Views
  • Uploaded on

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)

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' A quick Ruby Tutorial, Part 2' - horace


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
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

writing attributes
Writing attributes

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

simpler
Simpler

class Song

attr_writer :duration

end

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

song.duration = 257

virtual attributes
Virtual attributes

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

class variables
Class variables

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 methods
Class methods

class Example

def instance_method # instance method

end

def Example.class_method # class method

end

end

#uses:

Example.class_method

Example.new

singleton class example
Singleton class example

class MyLogger

private_class_method :new

@@logger = nil

def MyLogger.create

@@logger = new unless @@logger

@@logger

end

end

access control
Access control
  • 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!
how to define access
How to define access

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

alternatively
Alternatively

class MyClass

def method1

end

# ... and so on

public :method1, :method4

protected :method2

private :method3

end

account example
Account example

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

protected example
Protected example

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

assignment semantics like java
Assignment semantics (like Java)

person1 = "Tim"

person2 = person1

person1[0] = \'J\'

person1 → "Jim"

person2 → "Jim”

person1 = "Tim"

person2 = person1.dup

person1[0] = "J"

person1 → "Jim"

person2 → "Tim"

freeze objects
“freeze” objects

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

array access again
Array access (again)

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]

implement own sample container
Implement own sample container

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

defining array like access
Defining array-like access

class SongList

def [](index)

@songs[index]

end

end

unit testing
Unit testing

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

finding songs by title
Finding songs by title

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 the ruby way
Finding songs by title (the Ruby way)

class SongList

def with_title(title)

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

end

end

hypothetical find in array
Hypothetical find in Array

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

inject iterator
inject iterator

[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

iterators in ruby
Iterators in Ruby
  • are “internal”, I.e. just another method
  • Java et.al.: “external”, I.e. explicit additional object
  • pros and cons
more on code blocks
more on code blocks

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

proc and lambda
proc and lambda

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 "

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

num = 81

6.times do

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

num *= num

end

loops using numbers
Loops using numbers

3.times { print "X " }

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

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

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

strings to numbers
Strings to numbers
  • 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, " ”

}

song database
Song database

/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 fields

convert runtime into seconds

remove extra spaces in artists’ names

song database code
Song database: code

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

ad