"Simple #{multi_foo(2)}" "Interpolated foo foo foo "

10 0.5 0.0002 65535 8

Brian Schrder

Ruby Course 2004

Syntax: Variables, constants, methods, . . .

Variables / methods: student, i, epsilon, last_time Variables and methods look alike. This is reasonable because a variable can be substituted by a method. Constants: OldPerson, PDF_KEY, R2D2 Constants can only be dened once. Instance Variables: @name, @last_time, @maximum Instance variables can only be accessed by the owning object. Class Variables: @@lookup_table, @@instance Class variables belong not to the instances but to the class They exist only once for the class, and are shared by all instances. Global Variables: $global, $1, $count Usage of global variables has been declared a capital crime by the school of good design. Symbols: :name, :age, :Class Symbols are unique identiers, that we will encounter in various places.

Brian Schrder

Ruby Course 2004

Stylistic Rules

Variables and methods should be written in snake_case Class Names should be written in CamelCase Constants should be written ALL_UPPERCASE

Brian Schrder

Ruby Course 2004

Tools

Editors: Theses Editors are available under windows and linux xemacs Good highlighting and auto-indentation. Can be expanded to do everything. vim Good highlighting and auto-indentation. freeride Complete ruby ide written in ruby. ... and a lot more. For every 10 programmers you have 15 preferred editors. Interpreter: Each ruby script you write should be prexed by #!/usr/bin/ruby -w, to tell the system where the ruby interpreter is located. (The path may depend on the system.) Ruby Shell: The interactive ruby shell irb can be used to try out parts of the code. Ruby Documentation: Information about every class in ruby can be found using ri, the ruby interactive documentation system.

Brian Schrder

Ruby Course 2004

ri

ri is rubys fast helper $ ri String#tr String#tr str.tr(from_str, to_str) => new_str Returns a copy of str with the characters in from_str replaced by the corresponding characters in to_str. If to_str is shorter than from_str, it is padded with its last character. Both strings may use the c1c2 notation to denote ranges of characters, and from_str may start with a , which denotes all characters except those listed. "hello".tr(aeiou, *) "hello".tr(aeiou, *) "hello".tr(el, ip) "hello".tr(a-y, b-z) #=> #=> #=> #=> "h*ll*" "*e**o" "hippo" "ifmmp"

Ruby Course 2004

Exercises: Toolsirb and numbers: Open up irb and set the variables a = 1, b = 2. Calculate a/b. Calculate 1.0/2.0. Calculate 10200 . Write require complex into irb to load the Complex library Create a constant I set to Complex.new(0, 1) and calculate (1 + 2i ) (2 + 1i ) First program, string interpolation: Write a le answer.rb containing a function answer(a,b) that calculates a b and returns the string the answer is #{result of a b}.. Create a le answer containing the following lines:1 2 3

#!/usr/bin/ruby -w require answer puts answer(6, 7)

Make the le executable and call it. ri: Use ri to nd out how to make a string all uppercase, and try the function in irb.

{} "ruby" "banana" {"gemstone"=>"ruby", "fruit"=>"banana"}

{:july=>"ruby", :june=>"perl"} "ruby"

["Array", 1] ["Array", 2] {["Array", 1]=>:a1, ["Array", 2]=>:a2} :a1

Ruby Course 2004

Blocks and iterators

A function can take a block as an argument. A block is a piece of code, similar to an anonymous function, but it inherits the containing scope. Using iterators1 2

# A simple iterator, calling the block once for each entry in the array [i, am, a, banana].each do | entry | print entry, end i am a banana # Another commonly used iterator. The block is called in the scope where it was # created. fac = 1 1 1.upto(5) do | i | fac *= i end 1 fac 120 # The result of the block can be used by the caller [1,2,3,4,5].map { | entry | entry * entry } # and more than one argument is allowed (0..100).inject(0) { | result, entry | result + entry }

1 2 3 4 5 6 7 8 9 10 11

[1, 4, 9, 16, 25]

5050

Brian Schrder

Ruby Course 2004

Blocks and iterators

Block Syntax Blocks can be enclosed by do | | ... end.

1

[1,2,3,4,5].each do | e | puts e end

or by braces { | | ... }1

[1,2,3,4,5].map { | e | e * e }

[1, 4, 9, 16, 25]

A convention is to use do | | ... end wherever the side-eect is important and braces where the return value is important.

Ruby Course 2004

Blocks and iterators

Saving the block1 2 3 4 5 6 7 8 9 10 11 12 13 14

class Repeater def initialize(&block) @block = block @count = 0 end def repeat @count += 1 @block.call(@count) end end repeater = Repeater.new do | count | puts "You called me #{count} times" end 3.times do repeater.repeat end You called me 1 times You called me 2 times You called me 3 times

1 2 3

Brian Schrder

Ruby Course 2004

Exercises: IteratorsRefer to the exercise les for exact specication of the problems. n_times Write an iterator function n_times(n) that calls the given block n times. Write an iterator class Repeat that is instantiated with a number and has a method each that takes a block and calls it as often as declared when creating the object. Faculty Write a one-liner in irb using Range#inject to calculate 20!. Generalize this into a function. Maximum Write a function to nd the longest string in an array of strings. nd_it Write a function find_it that takes an array of strings and a block. The block should take two parameters and return a boolean value. The function should allow to implement longest_string, shortest_string, and other functions by changing the block.

4096 4096 4 65536 []

i *= 2 until (i >= 1000) nil i 1024

Ruby Course 2004

Exercises: Control Structures

Fibonacci Write functions that calculate the bonacci numbers using dierent looping constructs 8 i =0 < 0 1 i =1 b(i ) = : b(i 1) + b(i 2) otherwise recursion: Implement the function using recursion. while: Implement the function using a while loop. for: Implement the function using a for loop. times: Implement the function using the times construct. loop: Implement the function using the loop construct. Iterator Write a bonacci iterator function. That is a function that takes a number n and a block and calls the block with b(0), b(1), . . . b(n) Generator Write a bonacci generator class. That is: A class that has a next function which on each call returns the next bonacci number.Brian Schrder Ruby Course 2004

Ruby Course 2004

Exception Handling

Example: Usage in the chat server (Old code)

54 55 56 57 58 59 60 61 62 63

def listen @listen_thread = Thread.new do while line = @socket.gets break if /QUIT/ =~ line @on_received.call(self, line) if @on_received end @on_terminate.call(self) if @on_terminate @socket.close end end

Brian Schrder

Ruby Course 2004

Exception Handling

Example: Usage in the chat server (New code)

49 50 51 52 53 54 55 56 57 58 59 60 61

def listen @listen_thread = Thread.new do begin while line = @socket.gets break if /QUIT/ =~ line @on_received.call(self, line) if @on_received end ensure @on_terminate.call(self) if @on_terminate @socket.close end end end

Brian Schrder

Ruby Course 2004

A Simple Chat

Brian Schrder

Ruby Course 2004

Exercises: Exception Handling

Handshake Change the programs chat_03_client.rb and chat_03_server.rb to follow this protocol: 1. Client connects 2. Server sends YASC: 0.1 Server 3. Client sends YASC: 0.1 Client Exception Raising Raise an ENoYASCServer exception in the client, if the server is not sending the correct greeting string. Raise an ENoYASCClient exception in the server, if the client is not sending the correct greeting string. Exception Handling Terminate the client with a useful error message if a ENoYASCServer exception occurs. Close the clients socket and terminate clients-thread in the server if a ENoYASCClient exception occurs.

board = board[0, board[0, board[0, board[0,

Board.new(8, 8) 0] 0] = Cell.new() 0].state = :tower 0].state

Exercise: Accessor Functions

PersonName Create a class PersonName, that has the following attributes Name The name of the person. Surname The given name of the person. Fullname #{surname} #{name}. Add also a fullname setter function, that splits (String::split) the fullname into surname and name. Person Create a class Person, that has the following attributes Age The persons age (in years). Birthdate The persons birthdate. Name A PersonName object. The persons constructor should allow to pass in name, surname and age. All optionally. The persons age and birth date should always be consistent. That means if I set the persons birth date, his age should change. And if I set a persons age, his birth date should change.

Brian Schrder

Ruby Course 2004

Ruby is Dynamic

Classes, functions, modules can be modied at runtime.

25 26 27

class PersonShort < BasePerson attr_accessor :name, :surname end

attr_accessor is not a special language construct, but a function, that creates getter and setter functions for each argument.

Ruby Course 2004

Exercises: Extension of existing classes

Fibonacci II Extend Integer with a function b that calculates the corresponding bonacci number. Shue Extend Array with a method shue that creates a random permutation of the elements in the array.1 2 3

Ruby Course 2004

Exercises: Modules ITree Create a class TreeItem that has the following attributes: item That contains the list item used. left The left child of this item. right The right child of this item. each A function that takes a block and calls the block for each item in the subtree. Include the module Enumerable into the tree item. E.g.1 2 3 4 5 6 7 8 9 10 11

Ruby Course 2004

class TreeItem attr_accessor :left, :right, :item include Enumerable def initialize(item) self.item = item end def each(&block) block.call(self.item) left.each(&block) if left right.each(&block) if right end end

Exercises: Modules IIList Create a class ListItem that has the following attributes/methods: item That contains the list item used. previous The predecessor in the list. When this property is set the old and new predecessors next property should be updated. next The successor in the list. When this property is set the old and new successors previous should be updated. each Takes a block and calls the block for each item in the list. This should be done by following previous to the beginning of the list and then returning each item in list order. insert Inserts an item after this item into the list. Include the module Enumerable into the list item, such that the following constructs work. E.g.1 2 3 4 5 6 7 8

#<ListItem:... @next=#<L...> "List: zero one one point ve two three"

Brian Schrder

Ruby Course 2004

Part IV Regular Expressions

Brian Schrder

Ruby Course 2004

Regular ExpressionsAny character except \/^$|.+*?()[]\{\}, matches itself. ^ matches the start of a line, $ matches the end of a line. . matches any character. If a, b are regular expressions, then:ab is also a regular expression, that matches the concatenated strings. a* is a regular expression matching the hull of a. a+ is equivalent to aa*. a|b matches either a or b. Expressions can be grouped by brackets. E.g: (a|b)c matches {ac , bc }, a|bc matches {a , bc }.

[characters] Matches a range of characters. Example: [a-zA-Z0-9] matches the alphanumeric characters. [^characters] Matches the negation of a range of characters. Example: [^a-zA-Z0-9] matches all non-alphanumeric characters. +, and * are greedy, +?, *? are the non-greedy versions . (?=regexp) and (?!regexp) is positive and negative lookahead. There exist a couple of shortcuts for character classes. E.g. \w = [0-9A-Za-z_], \W = [^0-9A-Za-z_], \s = [ \t\n\r\f], \S = [^ \t\n\r\f], More information can be found at: http://www.regular-expressions.info/tutorial.html

10 nil 0 5 nil 0 0 nil

/name: "(.*)"/ #<MatchData:0x402c1fc0> "brian"

Ruby Course 2004

def showRE(string, regexp) if regexp =~ string then "#{$}<#{$&}>#{$}" else "no match" end end nil a = "The moon is made of cheese" showRE(a, /\w+/) showRE(a, /\s.*\s/) showRE(a, /\s.*?\s/) showRE(a, /[aeiou]{2,99}/) showRE(a, /mo?o/) "The moon is made of cheese" "<The> moon is made of cheese" "The< moon is made of >cheese" "The< moon >is made of cheese" "The m<oo>n is made of cheese" "The <moo>n is made of cheese"

Extract Username Write a regular expression that extracts the username from a string of the form USERNAME: Brian. Extract Version Number Include a function into the chat server that checks that the handshake string given by the chat client is correct, and returns the protocol version. If the string is not correct, raise an ENoYASCClient exception.

Ruby Course 2004

Unit TestingUnit tests are small programs, that compare the behaviour of your program against specied behaviour. Unit tests are collected while developing an application/library. Unit tests save you from breaking something with one change which you did not take into account when applying the change. Example1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Ruby Course 2004

Unit Testing - Examples

Test16 17 18 19 20

def test_negative assert_raise(ENegativeNumber, -1! should raise exception) do -1.fac end assert_raise(ENegativeNumber, -10! should raise exception) do -10.fac end assert_raise(ENegativeNumber, -111! should raise exception) do -111.fac end end

Ruby Course 2004

Unit Testing - Examples

Ruby Course 2004

Unit Testing - Examples

Test16 17 18 19 20

def test_negative assert_raise(ENegativeNumber, -1! should raise exception) do -1.fac end assert_raise(ENegativeNumber, -10! should raise exception) do -10.fac end assert_raise(ENegativeNumber, -111! should raise exception) do -111.fac end end