CSC/ECE 517 Summer 2008/wiki1 2 itr

From Expertiza_Wiki
Revision as of 00:26, 1 June 2008 by Jwpaul (talk | contribs)
Jump to navigation Jump to search

Introduction

One of the beloved feature of Ruby is the block based Iterator. A Ruby Iterator is simply a method that loops over the contents of an object without exposing its underlying representation. The verb `iterate' means "do the same thing many times' so `iterator' means "one which does the same thing many times'. It can also be considered as an object that behaves like a generic pointer. The iterator usually reference to one particular element in the object collection and then modify itself so that it points to the next element. Generators are a similar feature in Python. The name came as it is the entity which generate iterators. It allows you to write a function that can return a result and pause, resuming in the same place the next time you call the function. The generator feature in Ruby can be implemented by adding a library class called Generator or external iterator. In python the generator is a feature and part of the language.

Problem Definition

Ruby, like Java, has iterators to facilitate doing operations on each member of a set. Python has generators as well. Describe how generators differ from iterators, and find examples of code sequences using generators that would be awkward with iterators.

Iterator

The word "iterator" means different things in different contexts and programming languages, but it's always got something to do with visiting each one of a set of objects, where "object" doesn't necessarily mean "class instance": Just take "object" to mean "some instance of some data type, somewhere". Iterators may provide additional features or behaves in a different way depending on the languages.

Implementing Iterator

Most of the OOP languages provide ways to make iterations easy, for example some languages provide class controlling iteration, etc. But Ruby allows the definition of control structures directly. In terms of ruby, such user-defined control structures are called iterators. Examples of different iterators are given below.

Using Each

a = [ 1, 2, 3 ]
a.each { |x| print x }
==>1
   2
   3

x is the local variable in which each value of a is stored. And, each is probably the simplest iterator which yield successive elements of its collection.

Using Find

a = [ 1, 2, 3, 4, 5 ]
a.find { |n| n % 2 == 0 }
==>2

The find iterator method in ruby will compare each element using some comparison operator (<, >, ==, etc.) and based on the boolean result (true or false), it will return the first matching value.

Using Collect

a = [ 1, 2, 3, 4, 5 ]
b = a.collect { |n| n + 1 }
==>[2, 3, 4, 5, 6]

Another common iterator is the collect that returns an array of elements that is taken from the corresponding collections.

Generators

Generators are a simple and powerful tool for creating iterators. They are written like regular functions but use the yield statement whenever they want to return data. Each time next() is called, the generator resumes where it left-off (it remembers all the data values and which statement was last executed).

Using generator in python to count form 10 to 20

def countfrom(n):
   while True:
       yield n
       n += 1
for i in countfrom(10):
   if i <= 20:
       print i
   else:
       break

Note that this iteration terminates normally [1]

Using interator in Ruby to count form 10 to 20

a = [ 9,10,11,12,13,14,15,16,17,18,19 ]
b = a.collect { |n| n + 1 }
==>[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

We see this is not very eligant

Using generator in Ruby to count form 10 to 20

require 'generator'
gen = Generator.new(10..20)
while gen.next?
  print gen.next, ", "
end
==>10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,

With Rugy generators, we see the Ruby code flows similar to Python,

Comparisons of Ruby generators and Python generators

Python was intended to be a highly readable language. Ruby's internal iterators aren't always the best soltuion. Adding the generator or external iterators funtion helps get over the difficulty of writing the code and helps with the readablility. Ruby code runs slower than many compiled languages and other major scripting languages such as Python. Omission of parentheses around method arguments may lead to unexpected results if the methods take multiple parameters.

Ruby has a data type called Range; an object of this type constitutes a set of everything between the start and end of the range (including or not including the limits, depending on additional conditions). Since Range is a subclass of Enumerable, one would intuitively expect that iterating a valid Range object will give you every single object in that set, from start to end. This expectation turns out to be incorrect:[2]

irb(main):001:0> (1..3).each { |i| puts i }
1
2
3
=> 1..3
irb(main):002:0> (3..1).each { |i| puts i }
=> 3..1
irb(main):003:0>

in our previous example going from 20 to 10 may be difficult.


Numbering

  1. A
    1. a
  2. B
    1. b

Bullets

  • A
    • a
  • B
    • b

Subsubsection

Webmail [3]