Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Ruby ESA 2011/2012 Adam Belloum [email protected] Material Prepared by Eelco Schatborn ESA: Ruby • Today: 1. Ruby introducDon 2. Basic Ruby: types, variables, statements, . . . 3. Object Oriented Ruby: class, modules, … 4. DocumentaDon IntroducDon to Ruby • • • • • • Ruby was created by Yukihiro Matsumoto () a.k.a. “Matz” Introduced in 1994 Officially released by Matsumoto in 1995. “Ruby” was named as a gemstone as a joke. . . The TIOBE index, which measures the growth of programming languages, ranks Ruby as #9 among programming languages worldwide (2006) “trying to make Ruby natural, not simple,” “Ruby is simple in appearance, but is very complex inside, just like our human body” IntroducDon to Ruby • Ruby is "an interpreted scrip9ng language for quick and easy object‐oriented programming" ‐‐ what does this mean? • interpreted scrip+ng language: – ability to make operaDng system calls directly – powerful string opera9ons and regular expressions – immediate feedback during development h`p://www.rubyist.net/~slagell/ruby/index.html IntroducDon to Ruby • Ruby is "an interpreted scripDng language for quick and easy object‐oriented programming" ‐‐ what does this mean? • quick and easy: – variable declaraDons are unnecessary – variables are not typed – syntax is simple and consistent – memory management is automaDc h`p://www.rubyist.net/~slagell/ruby/index.html IntroducDon to Ruby • Ruby is "an interpreted scripDng language for quick and easy object‐oriented programming" ‐‐ what does this mean? • object oriented programming: – everything is an object – classes, methods, inheritance, etc. – "mixin" funcDonality by module – iterators and closures (h`p://www.arDma.com/intv/closures.html) h`p://www.rubyist.net/~slagell/ruby/index.html IntroducDon to Ruby • Ruby is "an interpreted scripDng language for quick and easy object‐oriented programming" ‐‐ what does this mean? • also: – mulDple precision numbers – convenient excep9on processing – dynamic loading – threading support. h`p://www.rubyist.net/~slagell/ruby/index.html Ruby, Perl and Python • Design goals – Expressive like perl but be`er Object‐OrientaDon – Like python but implemenDng true Object‐OrientaDon – No primi9ve types, everything is an object/class – Fully scriptable Simple Example #!/usr/bin/ruby def power(x,n) result = 1 x = x*x n = n/2 end return result end Ruby Basics • Normal method for scripDng using #!/usr/bin/ruby • irb is an interacDve ruby interpreter – You can interpret single lines of code – Good for simple checking and debugging • You can document Ruby code using the RDoc system – The documentaDon is inside the source file – It can be extracted using ri – To find the documentaDon for a class type ri classname at the command prompt Numbers Simple numbers: binary, start with 0b: 0b1100, ‐0b10001, 0b11111111 . . . decimal: 12, ‐17, 255 . . . octal, start with 0: 015, ‐023, 0777 . . . hexadecimal, start with 0x: 0xc, ‐0x11, 0xff, . . . floaDng point numbers: “one and a quarter ": 1.25 – scienDfic notaDon: “7.25 Dmes 10 to the 45th power ": 7.25e45. – – – – – But also matrices and complex numbers using separate modules Strings (1) • To create string literals, enclose them in single, or double quotes. • Examples: 'Hello Class of 2007' "Ruby is shiny” • The same type of quote used to start the string must be used to terminate it. • You can have your own delimiters using % %q!"I said 'nuts'", I said! # %q ‐ applies the simple quote rules %Q(It's like a " string,\n \\n is a newline) # %Q applies the double quote rules If you use () {} [] as delimiter you can use these delimiters as a text as long as they are in pairs Strings (2) • Escape sequences for single quoted (') strings: only \\ and \’ • For double quoted (‘”’) strings: \a, \b, \e, \f, \n, \r, \s, \t, • You can embed ruby code into a double quoted string using #{. . . }: "Seconds/day: #{24*60*60}” Seconds/day: 86400 Strings (3) • IntermiGant single and double quoted strings are concatenated to one object: "'Well'" ', he said, ' '"How are you?"’ 'Well', he said, "How Are You?” • You can construct a mulDline string using a “here document”: string = <<END_OF_STRING The Body of the string is the input lines up to one ending with the same text that followed the '<<' END_OF_STRING Variables and Constants • Ruby variables and constants hold references to objects. – The object decides the type, not the variable – Reassignment can change the type of the variable • Naming is as follows: Constants start with a [A-Z], the convenDon is to write all caps with underscores local variables start with a [a-z\_] global variables start with a `$' instance variables start with a `@’ class variables start with `@@’ Predefined variables • Most predefined variables come from perl • There are predefined variables for: Input/Output ($_, $., …) Pa`ern Matching ($=, $1 to $9, …) ExecuDon Environment (Ruby specific) ($0, $”, …) ExcepDon informaDon ($!, $@) Standard objects (true, false, ARGV, …) global Constants (STDIN, STDOUT, …) http://www.softlab.ntua.gr/facilities/ documentation/unix/ruby-man-1.4/ variable.html#equal String variables • String variables are indexed like lists, starDng at 0 • You can use them using the index operator `[i]' a = "Hello World" b = a[4] # b = o • Substrings can be used by pair numbers: `[start,count]' c = a[0,6] # c = "Hello " d = a[7,4] # d = "orld" e = a[3,5] # e = "lo Wo” • Ranges can also be used to specify indices. Ranges • Construct ranges of numbers or characters • Use double dot notaDon for inclusive range creaDon: 1..5 [1, 2, 3, 4, 5] • Use triple dot notaDon for exclusive range creaDon: 1...5 [1, 2, 3, 4] Example for string variables: a = "Hello World" c = a[0..5] # c = "Hello " d = a[7..10] # d = "orld" e = a[3...9] # e = ? Arrays • Arrays are arbitrary lists of objects • Create an Array using [ ]: names = [“Fred”,2,"Flintstone”] • They too are indexed: a = names[1] # a is now 2 names[0] = “Wilma” # names is changed • Using a range: names[1..2] [ 2, "Flintstone" ] Hashes (1) • A hash contains objects indexed by keys. • Any object can be used as a key or value, but . . . • Create a hash by enclosing `key => value’ combinaDons in curly braces (`{. . . }'): a = { "username" => "xenos", "home" => "/home/xenos”, "uid" => 500 } Hashes (2) • Access any value using it's key: u = a["username"] # Returns "xenos" d = a["home"] # Returns "/home/xenos” • To insert or modify objects, you assign a value to a key‐ indexed name. a["username"] = "trixie" a["home"] = "/home/trixie" a["shell"] = "/usr/bin/tcsh" Hashes (3) • Hash membership is tested with several methods: has_key?, has_value?, keys, values a.has_key? "username” # return True a.has_value? "trixie” # return false a.keys # ["xenos", 500, “/usr/bin/tcsh”, "/home/xenos”] a.values # ["username", "uid", "shell", "home"] Expressions • Single terms are: – Literals (numbers, strings, arrays, hashes, ranges, symbols, RE's) – Shell commands, using backquotes: `‘. . . ‘` files = ‘ls *‘ – Variable or constant references • Expression blocks are denoted by begin/do • The usual operators: . . . end +, -, *, /, %, **, !, … • Most operators are implemented as methods (may be overridden) Assignment • Using parallel assignment you can forego to use of temporary variables: a = 1 b = 2 temp = a a = b b = temp Using parallel assignment: a, b = b, a Comparison Operators == Test for equal value === Comparison operator for the case statement <=> General comparison operator (returns ‐1, 0, 1) <, <=, >, >= Normal comparison operators =~ Regular expression match eql? Checks for type and value equality equal? Checks for Object ID equality Flow control • Code blocks are denoted by { . . . } or do . . . end blocks • Code blocks can start with an argument list between verDcal bars: |…| • #!/usr/bin/ruby presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton”] presidents.each {|prez| puts prez} • Flow control can be exerted using looping or condi9onal statements. Looping Statements (1) • The standard constructs are present: while condition until condition body body end end • Using a begin . . . end block the syntax can be reversed: begin body end while condition begin body end until condition Looping Statements (2) • IteraDng over the members of a sequence containing any type of object. for i in [1,2,"three", 4, 5,'eleven', 7 ] print i," " end • You can also use a range: for i in 1..10 print i," " end Looping Statements (3) • Most standard object types also provide iterator methods Examples for numbers: 3.times do print "Hi! " end 0.upto(93) do print "Ha! " end • For arrays/files/etcetera there are: obj.each, obj.foreach, . . . CondiDonal statements (1) • if and unless statements: if test [ : | then] unless test [ : | then ] body body elsif test [ : | then ] else body body end else body end • You can also use them on expressions as modifiers: expression if test expression unless test CondiDonal Statements (2) • case statement compares each when clause to a target and executes the first match case target when comparison [: | then] body when comparison [: | then] body . . . [else body ] end h`p://ilikestu~log.com/2008/04/15/how‐to‐write‐case‐switch‐statements‐in‐ruby/ Regular Expressions • Regular expressions are an object of type Regexp • They can be created using: / pattern / [options] %r{ pattern } [options] Regexp.new(' pattern ' [ , options] ) • Most standard opDons and pa`erns are available • For more informaDon see the documentaDon • r1 = Regexp.new('^a-z+:\\s+\w+') #=> /^a-z+:\s+\w+/ a = "HELLO” case a when /^[a-z]*$/; print "Lower case\n” when /^[A-Z]*$/; print "Upper case\n” else; print "Mixed case\n” end Methods (1) • A method can have arguments, they are passed to the block as an array • A method will return the result of the last executed expression in the block as the return value • The return expression will exit the method immediately giving its argument as a return value Methods (2) • A simple method definiDon is as follows: def sayhi(name) print "Hi", name End • A definiDon using pre‐ini9alized arguments: def options(a=99, b=a+1) [ a, b ] end options [99, 100] options 1 [1, 2] options 2, 4 [2, 4] Methods (3) • super method is a special method for objects – It executes the funcDon of the same name in the parent object – to ensure crea9on or ini9aliza9on of parent objects • super with no arguments – Ruby sends a message to the parent of the current object, – to invoke a method of the same name as the method invoking super. – It automaDcally forwards the arguments that were passed to the method from which it's called. • super() with an empty argument list – it sends no arguments to the higher‐up method, even if arguments were passed to the current method. • super(a, b, c) with specific arguments – it sends exactly those arguments. Classes (1) A ruby class is an extension of the class Class Class names start with a [A-Z] Classes create a new namespace Classes can be nested, but they will not be made global, so instanDaDon requires the fully qualified classname • A simple example definiDon: • • • • class MyClass CONST = 12345 def f 'hello world' end end Classes (2) • Create an instance object from a class as follows: obj = MyClass.new • The class Class defines a method new which is responsible for the creaDon of an object of the class – The new method must call the super method to allow the parent class to be allocated, otherwise no objects of that class can be created. • The class Class also defines the method initialize, which will be invoked in a newly created object, it will receive the arguments passed to new. – The initialize method must also call super if the parent object is to be properly iniDalized Classes (3) • To use a method from an object use a dot notaDon: obj.f • To retrieve a constant from an object use the double colon notaDon: obj::CONST • Examples: obj.f # hello world obj::CONST # 12345 Classes (4) Class variables • class variables are variables shared between all objects of a class class Song @@plays = 0 def play @@plays += 1 "This song: Total #@@plays plays." end end Classes (5) Class methods ‐ object methods vs. class methods ‐ a class may need to provide methods that work without being Ded to any parDcular object. For example MyClass.new. • Example class Example def instMeth end def Example.classMeth end end # instance method # class method Modules (1) • Modules are a way of grouping together methods, classes, and constants. Modules give you two major benefits. – Modules provide a namespace and prevent name clashes. – Modules implement the mixin facility. • A Ruby Module is basically a class that cannot be instan9ated • MulDple modules may be created in a single source file • Use the definiDons in a module in the same way you would an (instanDated) object • A redefini9on of a module results in overloading that module Modules (2) • A module definiDon: CONST = "outer" module A CONST = 1 def A.method CONST + 1 end end • QuesDons: CONST A::CONST A.method "outer" 1 2 Modules (3) • A module definiDon with scope inheritance: CONST = "outer" module B def B.method CONST + "scope" end end • QuesDon: B.method "outerscope” Modules (4) • Modules can be included in the definiDon of another module or class use: include <module‐name> require <modules-name> • The including module will have access to all constants, variables, methods etcetera from the included module • A class may also include a module – The module will be treated as a superclass for the class – The module can also contain an ini9alize method Modules (5) module SillyModule def hello "Hello." end end class SillyClass include SillyModule End s = SillyClass.new Question s.hello ”Hello” Including Source files • Include Ruby source files into a program using load or require Load loads the referenced file each Dme it is called Useful for (re)loading source code generated at run‐ Dme require loads the referenced file only once require is a statement, it can be use anywhere statements are allowed. For instance from within an if statement. • Local variables in a loaded file are not propagated to the scope of the loading file DocumentaDon BOOKS!, they are in the back of the classroom. . . Use the web, there are good websites on ruby Check h`p://www.ruby‐lang.org/ for help. h`p://www.ruby‐doc.org/docs/ruby‐doc‐bundle/ index.html • “Programming Ruby", can be found online via above link • • • • Play Around • write a func9on fact to compute factorials. – The mathemaDcal definiDon of n factorial is: n! = 1 (when n==0) = n * (n‐1)! (otherwise) • write a simple ruby prog with case statement where given a model of a car it prints the brand • write a simple ruby prog with arrays, print the element of the array, remove elements, prepend elements – Hint: Ruby arrays have methods shi•, unshi•, push, and pop) • write a simple ruby with control statement if. When given democrats it prints the names of democrats presidents in US since 1976, same for republicans Play Around • write a class Decade and a module Week to print the number of weeks in a month, a year, and the number of days in a decade (include the Week module in the Class Decade) – • write a class with runDme Excep9on handling. If the age of a given paDent is bellow a certain age, it generate an excepDon. – Hints: use raise to generate the exp, and rescue to catch it Play Around • write a func9on fact to compute factorials. – The mathemaDcal definiDon of n factorial is: n! = 1 (when n==0) = n * (n‐1)! (otherwise) # Program to find the factorial of a number # Save this as fact.rb def fact(n) if n == 0 1 else n * fact(n-1) end end puts fact(ARGV[0].to_i) Play Around • write a simple ruby prog with case statement where given a model of a car it prints the brand car = "Patriot” manufacturer = case car when "Focus": "Ford" when "Navigator" then "Lincoln" when "Camry" then "Toyota" when "Civic" then "Honda" when "Patriot": "Jeep" when "Jetta" ; "VW" when "Ceyene” "Porsche” when "520i" then "BMW” else "Unknown" end puts "The " + car + " is made by " + manufacturer Play Around • • write a simple ruby prog with arrays, print the element of the array remove elements, prepend elements Hint: Ruby arrays have methods shi•, unshi•, push, and pop) #!/usr/bin/ruby presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"] presidents.each { |i| print i, "\n"} #Remove 3 elements from the array #!/usr/bin/ruby presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"] presidents.pop presidents.pop presidents.pop presidents.each { |i| print i, "\n"} Play Around • • write a simple ruby prog with arrays, print the element of the array, remove elements, and prepend elements Hint: Ruby arrays have methods shi•, unshi•, push, and pop) #!/usr/bin/ruby presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"] presidents.each { |i| print i, "\n"} #Prepend 3 elements to the array #!/usr/bin/ruby presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2”] presidents.unshift("Nixon") presidents.unshift("Johnson") presidents.unshift("Kennedy") presidents.each { |i| print i, "\n"} Play Around • write a simple ruby with control statement if. When given democrats it prints the names of democrats presidents in US since 1976, same for republicans #!/usr/bin/ruby democrats = ["Carter", "Clinton”] republicans = ["Ford", "Reagan", "Bush1", "Bush2”] party = ARGV[0] if party == nil print "Argument must be \"democrats\" or \"republicans\"\n" elsif party == "democrats" democrats.each { |i| print i, " "} print "\n" elsif party == "republicans" republicans.each { |i| print i, " "} print "\n" else print "All presidents since 1976 were either Democrats or Republicans\n" end Play Around • write a class Decade and a module Week to print the number of weeks in a month, a year, and the number of days in a decade (include the Week module in the Class Decade) #!/usr/bin/ruby !/usr/bin/ruby require "Week” module Week class Decade FIRST_DAY = "Sunday" include Week def Week.weeks_in_month no_of_yrs=10 def no_of_months puts “four weeks in a month" puts Week::FIRST_DAY end number=10*12 def Week.weeks_in_year puts number puts “52 weeks in a year" end end end end Play Around • write a class Decade and a module Week to print the number of weeks in a month, a year, and the number of days in a decade (include the Week module in the Class Decade) #!/usr/bin/ruby require "Week” class Decade include Week no_of_yrs=10 def no_of_months puts Week::FIRST_DAY number=10*12 puts number end end d1=Decade.new puts Week::FIRST_DAY Week.weeks_in_month Week.weeks_in_year d1.no_of_months Play Around • write a class with runDme Excep9on handling. If the age of a given paDent is bellow a certain age, it generate an excepDon. • Hints: use raise to generate the exp, and rescue to catch it class MedicareEligibilityException < RuntimeError def initialize(name, age) @name = name @age = age end def getName return @name end def getAge return @age end end … next page … Play Around def writeToDatabase(name, age) # This is a stub routine print "Diagnostic: ”,name, ”,age ", age, " is signed up.\n" end def signHimUp(name, age) if age >= 65 : writeToDatabase(name, age) else myException = MedicareEligibilityException.new(name, age) raise myException , "Must be 65 or older for Medicare", caller End end … next page … Play Around # Main routine begin signHimUp("Oliver Oldster", 78) signHimUp("Billy Boywonder", 18) signHimUp("Cindy Centurinarian", 100) signHimUp("Bob Baby", 2) rescue MedicareEligibilityException => elg print elg.getName, " is ", elg.getAge, ", which is too young.\n" print "You must obtain an exception from your supervisor. ", elg, "\n” end print "This happens after signHimUp was called.\n" Play Around • write a simple prog with two classes Mammal and cat the cat Class extends Mammal. • # class Mammal def breathe puts "inhale and exhale" end end class Cat<Mammal def speak puts "Meow" end end tama = Cat.new tama.breathe tama.speak Play Around • write a prog for reduced far for the train (3 Classes Traveler, Student, Honest, both Student and Honest inheritance class Traveler def identify puts "I'm a Traveler." end def train_toll(age) if age < 12 puts "Reduced fare."; else puts "Normal fare."; end end end Play Around class Student<Traveler def identify puts "I'm a student." end end class Honest<Traveler def train_toll(age) super(age) # pass the argument we were given end end Traveler.new.identify Student1.new.identify Honest.new.train_toll(25) Assignment We will be creaDng an Alumni database system. 1. create a class 'alumnus' to store a single person or alumnus in. Create a method for separately adding friends (by reference to an exisDng alumnus object!) 2. test the class by creaDng a group of alumni who are friends. 3. Not all alumni have to be direct friends, you can also have acquaintances. They are friends of your friends that are not your direct friend. So: a distance of 1 is your friend, a distance of 2 is an acquaintance and more than 2 is unknown. Assignment 4. create a class that prints informaDon about a single alumnus 4.1 create a method for prinDng all friends of the alumnus by name 4.2 create a method for prinDng all acquaintances of the alumnus by name 4.3 create a method that prints ALL connected alumni at any distance for the given alumnus. For each connecDon print the distance number, the type of relaDon and the alumni through which they are connected so:2 : acquaintance : eelco ‐> jarno ‐> karst implies that eelco knows karst through jarno, meaning jarno is a friend and karst is an acquaintance. Note that there can be mulDple ways that eelco knows karst, always choose the shortest route, and never show a connecDon twice