Ruby - Colorado School of Mines

Download Report

Transcript Ruby - Colorado School of Mines

and other languages…
 Method
 Procs
arguments (partly review)
 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

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
puts
puts
puts
puts
title("Ms. Jolene Juniper")
title("Dr. Cyndi Rader")
title("Mrs. Anne Smith", 4)
punctuation("OMG!!!", 3)
punctuation("How do you feel today?")
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


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?



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")
greeting(:title=>"Sir", :name=>"McCarthy",
:greet=>"Howdy")
Usage is similar to keyword args in other languages – like Python
 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?
 http://langexplr.blogspot.com/2007/09/r
ubys-yield-statement.html
 (example on next screen)
 Ruby's
yield statement gives control to a
user specified block from the method's
body.

class NumericSequences
def fibo(limit)
i=1
yield 1
yield 1
a=1
b=1
while (i < limit)
t=a
a=a+b
b=t
yield a
i = i+1
end
end
...
end



g = NumericSequences::new
g.fibo(10) {|x| print
"Fibonacci number: #{x}\n"}
The code in green is a block
that will is passed to the
method fibo, and will be
called every time control
reaches a yield statement
Does this need to be a class?
 Procs
have block-like behavior
 BUT, can pass multiple procs as function
parameters (can only pass one block)
 Lambdas have method-like behavior
 Both
 We
are instances of Proc
will do lambdas in Haskell
http://awaxman11.github.io/blog/2013/08/05/what-is-the-difference-between-a-block/
# 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.
Example from Ruby Prog Language
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 arg must be the last arg in list
Notice the use of &
Use of yield is more common
Could use yield with this method signature
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
 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 (via
arguments)
 f = Proc.new { |x, y|
 puts f.call(4,5)
 puts f.arity
x + y}
 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 if used with
optional args, etc.
class ToDo
def buyGroceries
puts "Buy Groceries"
end
def doHomework
puts "Do Homework"
end
end
todo = ToDo.new
todo.instance_eval("buyGroceries")