160 likes | 252 Views
Ruby Methods, Procs , etc. and other languages… . Topics. Method arguments Procs. Methods Arguments. Can have a default value (Hangman!) Can accept any number of arguments Can pass a hash Can treat block associated with method as a method argument. Default value.
E N D
Ruby Methods, Procs, etc. and other languages…
Topics Method arguments Procs
Methods Arguments Can have a default value (Hangman!) Can accept any number of arguments Can pass a hash Can treat block associated with method as a method argument
Default value Parameters with default parameters must be adjacent in parameter list (no longer need to be at end of list… but good practice) def title(name, len=3) name[0,len] end def punctuation(sentence, index=sentence.size-1) sentence[index, sentence.size-index] end puts title("Ms. Jolene Juniper") puts title("Dr. Cyndi Rader") puts title("Mrs. Anne Smith", 4) puts punctuation("OMG!!!", 3) puts punctuation("How do you feel today?")
Variable-length arg lists def limitedSum(max, *rest) sum = 0 rest.each {|num| sum += num } if sum > max max else sum end end puts limitedSum(20, 1,4,5) puts limitedSum(20, 10, 20, 30) puts limitedSum(20) # * in method invocation data = [1,4,5] puts limitedSum(20, *data) How would you write max or min? Similar to splat Put * before one parameter, it will be converted to an array of 0 or more args Put * in method invocation to convert array to separate arguments
Hashes for arguments With lots of arguments, it can be hard to remember order Solution: send hash May omit curly braces if hash is last or only argument (cleaner syntax). Called a bare hash. def greeting(args) greet = args[:greet] || "Hi" title = args[:title] || "Citizen" name = args[:name] puts "#{greet} #{title} #{name}" end greeting(:greet=>"Hello", :title=>"Sir", :name=>"McCarthy")
Blocks - review • Blocks are syntactic structures • May be identified by curly braces { … } • or starting keyword (e.g., do) sequence of expressions, keyword end • Blocks are not objects, but we can create objects that represent blocks. • OK… why?
Yield - review http://langexplr.blogspot.com/2007/09/rubys-yield-statement.html (example on next screen) Ruby's yield statement gives control to a user specified block from the method's body.
Yield example • class NumericSequencesdef fibo(limit)i= 1 yield1 yield1 a = 1 b = 1 while (i < limit) t = a a = a + b b = tyieldai= i+1 endend ...end • g = NumericSequences::new • g.fibo(10) {|x| print "Fibonacci number: #{x}\n"} • The code in green is a blockthat will is passed to the method fibo, and will be called every time control reaches a yieldstatement
Objects that represent blocks Procs have block-like behavior Lambdas have method-like behavior Both are instances of Proc We will do lambdas in Haskell
Create a Proc by method passing Example from Ruby Prog Language # generate sequence of n numbers m*i + c def sequence(n,m,c) i=0 while (i < n) yield i*m + c i += 1 end end sequence(5, 2, 4) { |x| puts x } Block is anonymous. Invoked via keyword (yield), not as explicit method call.
Pass block explicitly def sequence3(n,m,c, &b) i=0 while (i < n) b.call(i*m + c) # could still do yield i += 1 end end sequence3(5, 2, 4) { |x| puts x } Block still passed outside () Block argmustbe the last arg in list Use of yield is more common Could use yield with this method signature
Pass block as Proc object def sequence4(n,m,c, b) i=0 while (i < n) b.call(i*m + c) i += 1 end end p = Proc.new { |x| puts x } sequence4(5, 2, 4, p) Notice no & in arg list
What can we do with this? • Consider a method to encode data from a file. Pseudocode: • Open file • While more data • Read byte • Encrypt byte # based on block • Write byte • Note that a Proc represents a block – so it has access to surrounding environment
Create and call a Proc f = Proc.new { |x, y| x + y} puts f.call(4,5) puts f.arity A proc is not a method BUT, it is an object, and it includes a method named call This example invokes the method call on the object f to execute it. Also calls arity to determine number of arguments. Can be confusing is used with optional args, etc.
Call an instance method class ToDo def buyGroceries puts "Buy Groceries" end def doHomework puts "Do Homework" end end todo = ToDo.new todo.instance_eval("buyGroceries")