45
Blocks Blocks + + Iterators Iterators Blocks + Iterators Blocks + Iterators RUBY MADE SIMPLE August 08 2013 John R Schmidt

Ruby Made Simple: Blocks Plus Iterators

Embed Size (px)

Citation preview

BlocksBlocks++

IteratorsIterators

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

2

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLE

Traditional Loops

10 FOR N=1 TO 1020 PRINT "WE LOVE RUBY"30 RETURN

for ( int i=0; i<10; i++) { System.out.println("We love Ruby");}

200 J=0210 J=J+1220 S$=T$[J]230 IF S$="END" GOTO 300240 PRINT S$+" LOVES RUBY"250 GOTO 210

j = 0;name = rubyists[0];while (!name.equals( "empty") ) { message = name + " loves Ruby" System.out.println(message); name = rubyists[j]; j++;}

August 08 2013John R Schmidt

3

Similar structures exist in Ruby ...

for n in (1..10) do puts "We love Ruby"end

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

j = 0name = rubyists[0]while name != "empty" do puts "#{name} loves Ruby" j += 1 name = rubyists[j];end (also: until)

4

Similar structures exist in Ruby ...

… but Ruby has something even better ...

for n in (1..10) do puts "We love Ruby"end

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

j = 0name = rubyists[0]while name != "empty" do puts "#{name} loves Ruby" j += 1 name = rubyists[j];end (also: until)

5

It looks like this:

1.upto(10) { puts "We love Ruby" }

rubyists.each { |name| puts "#{name} loves Ruby" }

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

6

It looks like this:

1.upto(10) { puts "We love Ruby" }

rubyists.each { |name| puts "#{name} loves Ruby" }

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

What is it ?

7

1.upto(10) { puts "We love Ruby" }

rubyists.each { |name| puts "#{name} loves Ruby" }

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

This is the block

8

1.upto(10) { puts "We love Ruby" }

rubyists.each { |name| puts "#{name} loves Ruby" }

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

These are the iterators

9

rubyists.each { |name| puts "#{name} loves Ruby" }

rubyists.each do |person| full_name = person.name first = full_name.get_first_name first = first.downcase first[0] = first[0].upcase puts "#{first} loves Ruby"end

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

A block is a sequence of one or more executable Ruby statements.

10

rubyists.each { |name| puts "#{name} loves Ruby" }

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

The convention is to enclose one-line blocks in curly brackets.

{ }

11

rubyists.each do |name| full_name = person.name first = full_name.get_first_name first = first.downcase first[0] = first[0].upcase puts "#{first} loves Ruby"end

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

And enclose multi-line blocks with the do and end keywords.

12

10.times { puts "We love Ruby" }

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

The iterators are instance methods that operate on the object they belong to.

[1,2,3,4].map { |x| x**3 - x**2 }

rubyists.each { |name| puts "#{name} loves Ruby" }

1.upto(15) { |n| puts "Programmer number #{n} loves Ruby" }

13

10.times { puts "We love Ruby" }

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

So the syntax is the same as any other method call.

[1,2,3,4].map { |x| x**3 - x**2 }

rubyists.each { |name| puts "#{name} loves Ruby" }

1.upto(15) { |n| puts "Programmer number #{n} loves Ruby" }

14

10.times { puts "We love Ruby" }

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Except that the method call is followed by the block.

[1,2,3,4].map { |x| x**3 - x**2 }

rubyists.each { |name| puts "#{name} loves Ruby" }

1.upto(15) { |n| puts "Programmer number #{n} loves Ruby" }

15

1.upto(5) { |x| puts x**2 }

accounts.each do |account| account[:date_updated] = today account[:status] = :past_due if account[:balance] < 0.0 todays_batch << accountend

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Parameters supplied to the block are put at the beginning of the block inside "pipe" characters (vertical lines).

|var|

16

1.upto(5) { |x| puts x**2 }

accounts.each do |account| account[:date_updated] = today account[:status] = :past_due if account[:balance] < 0.0 todays_batch << accountend

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Parameters supplied to the block are put at the beginning of the block inside "pipe" characters (vertical lines).

17

1.upto(5) { |x| puts x**2 }

1491625

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

The block executes once for each value returned by the iterator method, using that value as the value for the parameter.

18

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

10.times { puts "We love Ruby" }

1.upto(10) { |n| puts @comments[n] }

max.downto(5) { |y| draw_box(xx,y) }

0.step (10.0,0.2) { |x| delta = base + x**3 }

Objects that have iterators are most commonly either numbers . . .

19

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

history.each { |point| plot(point) }

last_job.each_pair { |k,v| log_item[k] = v }

list.find { |task| task[:status] == :pending }

[1,2,3,4,5,6,7,8,9,10].find_all { |z| z%3 == 0 }

Objects that have iterators are most commonly either numbers . . .

or collections.

20

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

10.times { puts "We love Ruby" }

1.upto(10) { |n| puts @comments[n] }

max.downto(5) { |y| draw_box(xx,y) }

Numbers with iterator methods are usually integers.

df.step (10.0,0.2) { |x| delta = base + x**3 }

The step method can also be called on a real number object (Float class).

21

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Collection objects using iterators are usually arrays or hashes.

history.each { |point| plot(point) }

last_job.each_pair { |k,v| log_item[k] = v }

list.find { |task| task[:status] == :pending }

[1,2,3,4,5,6,7,8,9,10].find_all { |z| z%3 == 0 }

columns.map { |c| dot_product(c,row) }

22

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Collection objects using iterators are usually arrays or hashes.

history.each { |point| plot(point) }

last_job.each_pair { |k,v| log_item[k] = v }

list.find { |task| task[:status] == :pending }

[1,2,3,4,5,6,7,8,9,10].find_all { |z| z%3 == 0 }

columns.map { |c| dot_product(c,row) }

NOTE : There is no predefined class or module named Collection. "Collection" is merely a term used to describe objects that contain a group of items. Usually these are arrays or hashes, but also include specialized classes such as Set or Range.

23

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

timestimes 10.times { puts "We love Ruby" }

uptoupto 1.upto(10) { |n| puts @comments[n] }

downtodownto max.downto(5) { |y| draw_box(xx,y) }

stepstep df.step (10.0,0.2) { |x| delta = base_value + x**3 }

Common iterator methods for numbers

24

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

eacheach history.each { |point| draw_point(point) }

each_paireach_pair last_job.each_pair { |k,v| log_entry[k] = v }

findfind list.find { |task| task[:status] == :pending }

find_allfind_all [1,2,3,4,5,6,7,8,9,10].find_all { |z| z%3 == 0 }

Common iterator methods for collections

25

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

countcount history.each { |point| plot(point) }

mapmap columns.map { |c| dot_product(c,row) }

map!map! coordinates.map! { |c| standard_format(c) }

Common iterator methods for collections

26

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

times

upto

downto

step

count

map

map!

What do these do ?

each

each_pair

find

find_all

27

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

times

10.times { puts "We love Ruby" }

Iterates block int times, passing in values from zero to int - 1.

times { block }

Ruby 2.0 API :

● Method called upon an integer object.

● Executes the statements in the block as many times as the value of the integer.

● Values passed to the block as a parameter iterate from zero to the value of the integer object minus 1.

28

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

upto

1.upto(10) { |n| puts @comments[n] }

Iterates block, passing in integer values from int up to and including limit.

upto(limit) {|int| block }

Ruby 2.0 API :

● Method called upon an integer object, with another integer as the method's parameter.

● Iterates from the value of the integer object to the value of the method's parameter, incrementing by 1 for each iteration.

● Executes the block with each iteration and passes the value of the iteration to the block parameter.

29

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

downto

max.downto(5) { |y| draw_box(xx,y) }

Iterates block, passing decreasing values from int down to and including limit.

downto(limit) {|int| block }

Ruby 2.0 API :

● Method called upon an integer object, with another integer as the method's parameter.

● Iterates downward from the value of the integer object to the value of the method's parameter, decrementing by 1 for each iteration.

● Executes the block with each iteration and passes the value of the iteration to the block parameter.

30

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

step

10.step (100,5) { |n| sigma += t/n }

df.step (10.0,0.2) { |x| delta = base_value + x**3 }

Invokes block with the sequence of numbers starting at num, incremented by step on each call.

step(limit, step) {|int| block }

Ruby 2.0 API :

● Method called upon a numeric object, with two numeric parameters.

● Iterations begin at the value of the object and are incremented by the value of the second parameter, which can be positive or negative.

● Iterations end at the maximum value less than or equal to the first parameter (or the minimum for negative iterations).

31

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

each

history.each { |point| draw_point(point) }

Calls the given block once for each element in self, passing that element as a parameter.

each { |item| block }

Ruby 2.0 API :

● Method called upon an array, a hash, or other "collection" object.

● Iterates once for each item in the collection, passing that item as the parameter.

● Iterates through a hash in the order the pairs were added in Ruby 1.9 and 2.0. Order is not guaranteed in Ruby 1.8 and older.

32

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

each_pair

last_job.each_pair { |k,v| log_item[k] = v }

Calls block once for each key in hash, passing the key-value pair as parameters.

each {| key, value | block }

Ruby 2.0 API :

● Method called upon a hash object.

● Iterates once for each key-value pair in the hash, passing each key and its corresponding value as the parameters.

● The block's parameter declaration should have two parameters, one for key and one for value.

33

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

find

list.find { |task| task[:status] == :pending }

Returns the first entry for which block is not false.

find { |obj| block }

Ruby 2.0 API :

● Method called upon a collection object.

● Returns the first object it finds for which the block returns true.

34

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

find_all

[1,2,3,4,5,6,7,8,9,10].find_all { |z| z%3 == 0 }

Returns an array containing all elements for which the given block returns true.

find_all { |obj| block }

Ruby 2.0 API :

● Method called upon a collection object.

● Returns an array containing all items in the collection for which the block returns true.

( ALIAS: select )

35

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

count

failures = attempts.count { |z| z[:status] == :fail }

Counts the number of elements for which the block returns true.

count { |item| block }

Ruby 2.0 API :

● Method called upon a collection object.

● Returns an integer representing the number of objects in the collection for which the block returns true.

36

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

map

columns.map { |c| dot_product(c,row) }

Creates a new array containing the values returned by the block.

map { |item| block }

Ruby 2.0 API :

● Method called upon a collection object.

● Iterates once for each item in the collection, passing that item as the parameter.

● Returns an array with the same number of elements as the collection, using each member of the collection as the parameter supplied to the block.

37

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

map!

coordinates.map! { |c| standard_format(c) }

Replaces each element with the value returned by the block.

map! {|item| block }

Ruby 2.0 API :

● The "destructive version" of the map method. Available to arrays only.

● Same as the map method, except that the values of the original array are changed to the new values determined by the statements in the block.

38

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Beyond MADE SIMPLE

● detect, select, reject, collect, inject, inspect

● inject/ reduce

● cycle

● Internal iterators/ external iterators

● Define or overwrite your own iterator

● Mix in Enumerable

39

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Beyond MADE SIMPLE

● detect, select, reject, collect, inject, inspect

Rhyming alias names for find, find_all, opposite of find_all, map, reduce and to_s

● inject/ reduce

● cycle

● Internal iterators/ external iterators

● Define or overwrite your own iterator

● Mix in Enumerable

40

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Beyond MADE SIMPLE

● detect, select, reject, collect, inject, inspect

● inject/ reduce

"Inject" a function (+,-,*, …) or method into a collection to "reduce" it to a single value.

● cycle

● Internal iterators/ external iterators

● Define or overwrite your own iterator

● Mix in Enumerable

41

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Beyond MADE SIMPLE

● detect, select, reject, collect, inject, inspect

● inject/ reduce

● cycle

Executes the block repeatedly until stopped by something else, such as end of input, an exception or error, or turning off the machine.

● Internal iterators/ external iterators

● Define or overwrite your own iterator

● Mix in Enumerable

42

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Beyond MADE SIMPLE

● detect, select, reject, collect, inject, inspect

● inject/ reduce

● cycle

● Internal iterators/ external iterators

Methods that iterate over their own objects are called "internal iterators". A separate object that iterates over other objects is called an "external iterator". You can define external iterators in Ruby, if you wish.

● Define or overwrite your own iterator

● Mix in Enumerable

43

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Beyond MADE SIMPLE

● detect, select, reject, collect, inject, inspect

● inject/ reduce

● cycle

● Internal iterators/ external iterators

● Define or overwrite your own iterator

Write a custom each or other iterator method for your classes.

● Mix in Enumerable

44

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Beyond MADE SIMPLE

● detect, select, reject, collect, inject, inspect

● inject/ reduce

● cycle

● Internal iterators/ external iterators

● Define or overwrite your own iterator

● Mix in Enumerable

Declare your class with the Enumerable mix-in, define an each method, and you get other methods such as map, find and include? for free. Define a comparator <=> and you also get min, max, sort, etc.

45

Blocks + IteratorsBlocks + Iterators

RUBY MADE SIMPLEAugust 08 2013John R Schmidt

Blocks + IteratorsBlocks + Iterators