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")