Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "A quick Ruby Tutorial, Part 3 COMP313 Source: Programming Ruby, The Pragmatic Programmers’ Guide by Dave Thomas, Chad Fowler, and Andy Hunt."— Presentation transcript:

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

2 class WordIndex def initialize @index = {} end def add_to_index(obj, *phrases) phrases.each do |phrase| phrase.scan(/\w[-\w']+/) do |word| # extract each word word.downcase! @index[word] = [] if @index[word].nil? @index[word].push(obj) end def lookup(word) @index[word.downcase] end Index by each word

3 Add full index to SongList class SongList def initialize @songs = Array.new @index = WordIndex.new end def append(song) @songs.push(song) @index.add_to_index(song, song.name, song.artist) self end def lookup(word) @index.lookup(word) end

4 Ranges 1..10 'a'..'z' my_array = [ 1, 2, 3 ] 0...my_array.length (1..10).to_a → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ('bar'..'bat').to_a → ["bar", "bas", "bat"] digits = 0..9 digits.include?(5) → true digits.min → 0 digits.max → 9 digits.reject {|i| i < 5 } → [5, 6, 7, 8, 9] digits.each {|digit| dial(digit) } → 0..9

5 Range example: VU meter class VU include Comparable attr :volume def initialize(volume) # 0..9 @volume = volume end def inspect '#' * @volume end # Support for ranges def (other) self.volume other.volume end def succ raise(IndexError, "Volume too big") if @volume >= 9 VU.new(@volume.succ) end

6 VU Ranges / Ranges in conditions medium_volume = VU.new(4)..VU.new(7) medium_volume.to_a → [####, #####, ######, #######] medium_volume.include?(VU.new(3)) → false (1..10) === 5 → true (1..10) === 15 → false (1..10) === 3.14159 → true ('a'..'j') === 'c' → true ('a'..'j') === 'z' → false

7 Regular expressions a = Regexp.new('^\s*[a-z]') → /^\s*[a-z]/ b = /^\s*[a-z]/ → /^\s*[a-z]/ c = %r{^\s*[a-z]} → /^\s*[a-z]/ name = "Fats Waller" name =~ /a/ → 1 name =~ /z/ → nil /a/ =~ name → 1

8 Special vars $` $& $’ def show_regexp(a, re) if a =~ re "#{$`} >#{$'}" else "no match" end show_regexp('very interesting', /t/) → very in >eresting show_regexp('Fats Waller', /a/) → F >ts Waller show_regexp('Fats Waller', /ll/) → Fats Wa >er show_regexp('Fats Waller', /z/) → no match

9 Special chars, anchors., |, (, ), [, ], {, }, +, \, ^, $, *, and ? show_regexp('kangaroo', /angar/) → k >oo show_regexp('!@%&-_=+', /%&/) → !@ >-_=+ show_regexp("this is\nthe time", /^the/) → this is\n > time show_regexp("this is\nthe time", /is$/) → this >\nthe time show_regexp("this is\nthe time", /\Athis/) → > is\nthe time show_regexp("this is\nthe time", /\Athe/) no match

10 More RegExps show_regexp('Price $12.', /[aeiou]/) → Pr >ce $12. show_regexp('Price $12.', /[\s]/) → Price >$12. show_regexp('Price $12.', /[[:digit:]]/) → Price $ >2. show_regexp('Price $12.', /[[:space:]]/) → Price >$12. show_regexp('Price $12.', /[[:punct:]aeiou]/) → Pr >ce $12. a = 'see [Design Patterns-page 123]' show_regexp(a, /[A-F]/) → see [ >esign Patterns-page 123] show_regexp(a, /[A-Fa-f]/) → s >e [Design Patterns-page 123] show_regexp(a, /[0-9]/) → see [Design Patterns-page >23] show_regexp(a, /[0-9][0-9]/) → see [Design Patterns-page >3]

11 character classes \d [0-9] Digit character \D [^0-9] Any character except a digit \s [ \t\r\n\f] Whitespace character \S [^ \t\r\n\f] Any character except whitespace \w [A-Za-z0-9_] Word character \W [^A-Za-z0-9_] Any character except a word character

12 Repetition r* matches zero or more occurrences of r. r+ matches one or more occurrences of r. r? matches zero or one occurrence of r. r{m,n} matches at least m and at most n occurrences of r. r{m,} matches at least m occurrences of r. r{m} matches exactly m occurrences of r. /ab+/ matches ab, abb, abbbb, … /(ab)+/ matches ab, abab, ababab, … /a*/ matches everything (why?)

13 Greedy matching/Alternatives a = "The moon is made of cheese" show_regexp(a, /\w+/) → > moon is made of cheese show_regexp(a, /\s.*\s/) → The >cheese show_regexp(a, /\s.*?\s/) → The >is made of cheese show_regexp(a, /[aeiou]{2,99}/) → The m >n is made of cheese a = "red ball blue sky" show_regexp(a, /d|e/) → r >d ball blue sky show_regexp(a, /al|lu/) → red b >l blue sky show_regexp(a, /red ball|angry sky/) → > blue sky

14 Groupings show_regexp('banana', /an*/) → b >ana show_regexp('banana', /(an)*/) → >banana show_regexp('banana', /(an)+/) → b >a a = 'red ball blue sky' show_regexp(a, /blue|red/) → > ball blue sky show_regexp(a, /(blue|red) \w+/) → > blue sky show_regexp(a, /(red|blue) \w+/) → > blue sky show_regexp(a, /red|blue \w+/) → > ball blue sky show_regexp(a, /red (ball|angry) sky/) → no match a = 'the red angry sky' show_regexp(a, /red (ball|angry) sky/) → the >

15 Groupings collect matches "12:50am" =~ /(\d\d):(\d\d)(..)/ → 0 "Hour is #$1, minute #$2" → "Hour is 12, minute 50" "12:50am" =~ /((\d\d):(\d\d))(..)/ → 0 "Time is #$1" → "Time is 12:50" "Hour is #$2, minute #$3" → "Hour is 12, minute 50" "AM/PM is #$4" → "AM/PM is am"

16 Match inside with \1,… # match duplicated letter show_regexp('He said "Hello"', /(\w)\1/) → He said "He >o" # match duplicated substrings show_regexp('Mississippi', /(\w+)\1/) → M >ippi show_regexp('He said "Hello"', /(["']).*?\1/) → He said > show_regexp("He said 'Hello'", /(["']).*?\1/) → He said >

17 Substitute patterns a = "the quick brown fox" a.sub(/[aeiou]/, '*') → "th* quick brown fox" a.gsub(/[aeiou]/, '*') → "th* q**ck br*wn f*x" a.sub(/\s\S+/, '') → "the brown fox" a.gsub(/\s\S+/, '') → "the" a.sub(/^./) {|match| match.upcase } → "The quick brown fox" a.gsub(/[aeiou]/) {|vowel| vowel.upcase } → "thE qUIck brOwn fOx"

18 Upcase every first char def mixed_case(name) name.gsub(/\b\w/) {|word| word.upcase } end mixed_case("fats waller") → "Fats Waller" mixed_case("louis armstrong") → "Louis Armstrong" mixed_case("strength in numbers") → "Strength In Numbers"

19 Classes behind regexps re = /(\d+):(\d+)/ # match a time hh:mm re.class -> Regexp md = re.match("Time: 12:34am") md.class → MatchData md[0] → "12:34" # $& md[1] → "12" # $1 md[2] → "34" # $2 md.pre_match → "Time: ” # $` md.post_match → "am" # $’

20 optional args for methods def cool_dude(arg1="Miles", arg2="Coltrane", arg3="Roach") "#{arg1}, #{arg2}, #{arg3}." end cool_dude → "Miles, Coltrane, Roach." cool_dude("Bart") → "Bart, Coltrane, Roach." cool_dude("Bart", "Elwood") → "Bart, Elwood, Roach." cool_dude("Bart", "Elwood", "Linus") → "Bart, Elwood, Linus."

21 Variable number of args def varargs(arg1, *rest) "Got #{arg1} and #{rest.join(', ')}" end varargs("one") → "Got one and " varargs("one", "two") → "Got one and two" varargs "one", "two", "three" → "Got one and two, three"

22 code blocks again def take_block(p1) if block_given? yield(p1) else p1 end take_block("no block") → "no block" take_block("no block") {|s| s.sub(/no /, ‘’) } → "block"

23 Capture block explicitly class TaxCalculator def initialize(name, &block) @name, @block = name, block end def get_tax(amount) "#@name on #{amount} = #{ @block.call(amount) }" end tc = TaxCalculator.new("Sales tax") {|amt| amt * 0.075 } tc.get_tax(100) → "Sales tax on 100 = 7.5" tc.get_tax(250) → "Sales tax on 250 = 18.75"

24 Calling a method connection.download_MP3("jitterbug") {|p| show_progress(p) } File.size("testfile") → 66 Math.sin(Math::PI/4) → 0.707106781186548 self.class → Object self.frozen? → false frozen? → false self.object_id → 969948 object_id → 969948

25 Multiple return values def some_method 100.times do |num| square = num*num return num, square if square > 1000 end some_method → [32, 1024] num, square = some_method num → 32 square → 1024

26 Expanding arrays into args def five(a, b, c, d, e) "I was passed #{a} #{b} #{c} #{d} #{e}" end five(1, 2, 3, 4, 5 ) → "I was passed 1 2 3 4 5" five(1, 2, 3, *['a', 'b']) → "I was passed 1 2 3 a b" five(*(10..14).to_a) → "I was passed 10 11 12 13 14"

27 & for procedure objects print "(t)imes or (p)lus: " times = gets print "number: " number = Integer(gets) if times =~ /^t/ calc = lambda {|n| n*number } else calc = lambda {|n| n+number } end puts((1..10).collect(&calc).join(", ")) (t)imes or (p)lus: t number: 2 2, 4, 6, 8, 10, 12, 14, 16, 18, 20

28 Keyword args: use Hash class SongList def create_search(name, params) #... end list.create_search("short jazz songs", { 'genre' => "jazz", 'duration_less_than' => 270 }) list.create_search('short jazz songs', 'genre' => 'jazz', 'duration_less_than' => 270)

29 Expression fun a = b = c = 0 → 0 [ 3, 1, 7, 0 ].sort.reverse → [7, 3, 1, 0] song_type = if song.mp3_type == MP3::Jazz if song.written < Date.new(1935, 1, 1) Song::TradJazz else Song::Jazz end else Song::Other end

30 More expressions rating = case votes_cast when 0...10 then Rating::SkipThisOne when 10...50 then Rating::CouldDoBetter else Rating::Rave end command expressions: `date` → "Mon Jan 16 22:32:17 CST 2006\n"


Download ppt "A quick Ruby Tutorial, Part 3 COMP313 Source: Programming Ruby, The Pragmatic Programmers’ Guide by Dave Thomas, Chad Fowler, and Andy Hunt."

Similar presentations


Ads by Google