[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Enumerable

Michael Saltzman

8/1/2006 3:43:00 PM

Am new to Ruby and have the folloiwng Question.

I have a class, say Collect, and I want to mixin Enumerable. How do I
write the each method in Collect?

class Collect
include Enumerable
def initialize()
@array = Array.new(0)
@ct = 0
end
def add(item)
@array.push(item)
@ct += 1
end
def howmany
@ct
end
def each
#
# Not sure how to do this????
#
end
end

--
Posted via http://www.ruby-....

4 Answers

Martin DeMello

8/1/2006 4:04:00 PM

0

On 8/1/06, Michael Saltzman <michael@trainingetc.com> wrote:
> Am new to Ruby and have the folloiwng Question.
>
> I have a class, say Collect, and I want to mixin Enumerable. How do I
> write the each method in Collect?
>
> class Collect
> include Enumerable
> def initialize()
> @array = Array.new(0)
> @ct = 0
> end
> def add(item)
> @array.push(item)
> @ct += 1
> end
> def howmany
> @ct
> end
> def each
> #
> # Not sure how to do this????
> #
> end
> end

Assuming you want to iterate over @array,

def each
@array.each {|i| yield i}
end

martin

A. S. Bradbury

8/1/2006 4:06:00 PM

0

On Tuesday 01 August 2006 16:43, Michael Saltzman wrote:
> Am new to Ruby and have the folloiwng Question.
>
> I have a class, say Collect, and I want to mixin Enumerable. How do I
> write the each method in Collect?
>
> class Collect
> include Enumerable
> def initialize()
> @array = Array.new(0)
> @ct = 0
> end
> def add(item)
> @array.push(item)
> @ct += 1
> end
> def howmany
> @ct
> end
> def each
> #
> # Not sure how to do this????
> #
> end
> end
It depends what you want each to do? Just to wrap @array.each? In that case,
this would work:
def each
@array.each {|item| yield item}
end

Of course you can do whatever you want to the array item in the block before
you yield it again.

An alternative technique is as follows:
def each(&block)
@array.each(&block)
end

I'm sure someone will correct me if I describe this slightly wonky, but the
basic idea is that the interpreter converts the block argument to a proc with
a name (I think I read an article that claimed a block is always converted to
a proc, but when no &arg is given, it is simply a proc with no name,
accessible of course via yield). This is then passed on to @array.each as a
block argument.

I don't know whether there are any real advantages or disadvantages to either
method. Hope this helps

Alex

Robert Klemme

8/1/2006 4:16:00 PM

0

Michael Saltzman wrote:
> Am new to Ruby and have the folloiwng Question.
>
> I have a class, say Collect, and I want to mixin Enumerable. How do I
> write the each method in Collect?
>
> class Collect
> include Enumerable
> def initialize()
> @array = Array.new(0)
> @ct = 0
> end
> def add(item)
> @array.push(item)
> @ct += 1
> end
> def howmany
> @ct
> end
> def each
> #
> # Not sure how to do this????
> #
> end
> end
>

You have several options:

class Collect
include Enumerable

def initialize()
@array = []
end

def add(item)
@array.push(item)
self
end

alias :<< :add

def howmany
@array.size
end

# option 1: use yield
def each_1
@array.each {|x| yield x}
self
end

# option 2: delegate to Array's each
def each_2(&b)
@array.each(&b)
self
end
end

Kind regards

robert

A. S. Bradbury

8/1/2006 4:30:00 PM

0

On Tuesday 01 August 2006 17:06, A. S. Bradbury wrote:
> It depends what you want each to do? Just to wrap @array.each? In that
> case, this would work:
> def each
> @array.each {|item| yield item}
> end
>
> Of course you can do whatever you want to the array item in the block
> before you yield it again.
>
> An alternative technique is as follows:
> def each(&block)
> @array.each(&block)
> end
>
<snip>
> I don't know whether there are any real advantages or disadvantages to
> either method. Hope this helps

Just did a quick benchmark out of curiosity:
user system total real
Two yields 15.720000 2.220000 17.940000 ( 20.336562)
Pass the named block 4.130000 1.020000 5.150000 ( 5.562950)
Direct on attr_accessor 3.810000 1.010000 4.820000 ( 5.440259)

I passed the block {|i| i} and initialized @array to (1..100).to_a, and ran
through 50000 times.

Alex