implementing the "each" method for own classes

P

Philipp Huber

hello!

first of all, i'm new to ruby and this list.

my question is, i have a class "Queue" which implements a queue as
linked list of "Item" objects. i'd like to implement an each method,
so i can do something like

queue.each do |item|
item.do_somethng
end

any help would be appreciated!
thanks,
philipp
 
B

Brian Schröder

hello!
=20
first of all, i'm new to ruby and this list.
=20
my question is, i have a class "Queue" which implements a queue as
linked list of "Item" objects. i'd like to implement an each method,
so i can do something like
=20
queue.each do |item|
item.do_somethng
end
=20
any help would be appreciated!
thanks,
philipp
=20
=20

It is a bit hard to help you, if we don't know your classes. But lets
say you have a class
class QueueNode
attr_accessor :next
...
end=20

and a class Queue with a variable @root holding the first entry of the
queue you could implement each as

class Queue
...

def each(&block)
node =3D @root
begin
block[node]=20
end while node =3D node.next
end
end

or you could use yield
=20
class Queue
...

def each
node =3D @root
begin
yield node
end while node =3D node.next
end
end

that depends on personal preference.

hope to help,

Brian
--=20
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/
 
P

Philipp Huber

thanks a lot, works exactly as i wanted :)

hello!

first of all, i'm new to ruby and this list.

my question is, i have a class "Queue" which implements a queue as
linked list of "Item" objects. i'd like to implement an each method,
so i can do something like

queue.each do |item|
item.do_somethng
end

any help would be appreciated!
thanks,
philipp
=20
It is a bit hard to help you, if we don't know your classes. But lets
say you have a class
class QueueNode
attr_accessor :next
...
end
=20
and a class Queue with a variable @root holding the first entry of the
queue you could implement each as
=20
class Queue
...
=20
def each(&block)
node =3D @root
begin
block[node]
end while node =3D node.next
end
end
=20
or you could use yield
=20
class Queue
...
=20
def each
node =3D @root
begin
yield node
end while node =3D node.next
end
end
=20
that depends on personal preference.
=20
hope to help,
=20
Brian
--
http://ruby.brian-schroeder.de/
=20
Stringed instrument chords: http://chordlist.brian-schroeder.de/
=20
 
R

Robert Klemme

Philipp said:
thanks a lot, works exactly as i wanted :)

Two remarks:

- did you test this with an empty queue (I guess in that case @root will
be empty so you'll likely need something like

n = @root
while n
yield n.element
n = n.next
end

- by convention #each returns self which wasn't show in Brian's example.

Kind regards

robert
 
P

Philipp Huber

actually i did test it with a queue filled with a few elements. as you
said the condition for the while loop should be testet at the
beginning, otherwise nil could be returned.
so my code looks like this:

def each
node=3D@head
while node=3Dnode.next
yield node.content
end
end

do you have an example for the second remark, as i don't quite
understand what you mean

thanks,
philipp
 
B

Brian Schröder

actually i did test it with a queue filled with a few elements. as you
said the condition for the while loop should be testet at the
beginning, otherwise nil could be returned.
so my code looks like this:
=20
def each
node=3D@head
while node=3Dnode.next
yield node.content
end
end
=20
do you have an example for the second remark, as i don't quite
understand what you mean
=20
thanks,
philipp
=20
=20

Sorry for posting something that untested. But as I look again you
continue to have bugs in your code.

You are missing the first element. The following should work and also
return self. That allows you to do something like the following:

queue.each do | element | element.seen +=3D 1 end.each do | element |
puts element end

Beware that the above example does not make that much sense, but I do
not have a better example ready.

def each
node=3D@head
while node
yield node.content
node=3Dnode.next
end
self
end

hope to help

Brian

--=20
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/
 
R

Robert Klemme

Just put "return self" or just "self" in the last line of your method
#each.
Sorry for posting something that untested. But as I look again you
continue to have bugs in your code.

You are missing the first element. The following should work and also
return self. That allows you to do something like the following:

That's only true if head is nil for an empty queue. There are
implementations out there (for example java.util.LinkedList) where the
first element is never null. It might be though that it makes sense only
for a doubly linked list.
queue.each do | element | element.seen += 1 end.each do | element |
puts element end

Beware that the above example does not make that much sense, but I do
not have a better example ready.

def each
node=@head
while node
yield node.content
node=node.next
end
self
end

That's what I suggested, isn't it?

Kind regards

robert
 
B

Brian Schröder

hello!
=20
first of all, i'm new to ruby and this list.
=20
my question is, i have a class "Queue" which implements a queue as
linked list of "Item" objects. i'd like to implement an each method,
so i can do something like
=20
queue.each do |item|
item.do_somethng
end
=20
any help would be appreciated!
thanks,
philipp
=20
=20

Just one more hint in case you didn't know it. You should do

class Queue
include Enumerable
...
end

to get all the nice Enumerable methods for free.
all?, any?, collect, detect, each_with_index, entries, find,
find_all, grep, include?, inject, map, max, member?, min,
partition, reject, select, sort, sort_by, to_a, to_set, zip

regards,

Brian

--=20
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/
 
P

Philipp Huber

of course your right, my variant leaves out the first element.
what's actually the sense behind returning self?
 
R

Robert Klemme

Philipp said:
of course your right, my variant leaves out the first element.
what's actually the sense behind returning self?

Don't ask. There's a dark secret connected to this. Noone ever lived to
tell. Many have tried to provide explanations (such as support of method
chaining) but the truth was never revealed...

;-)

Cheers

robert
 
B

Brian Schröder

=20
Just put "return self" or just "self" in the last line of your method
#each.
=20
=20
That's only true if head is nil for an empty queue. There are
implementations out there (for example java.util.LinkedList) where the
first element is never null. It might be though that it makes sense only
for a doubly linked list.
=20
=20
That's what I suggested, isn't it?

It is - I'm sorry, I'm task-switching in my mind too fast at the
moment. I will concentrate on my thesis now ...

best regards,

Brian
=20
Kind regards
=20
robert
=20
=20
=20


--=20
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/
 
D

Daryl Richter

Robert said:
Don't ask. There's a dark secret connected to this. Noone ever lived to
tell. Many have tried to provide explanations (such as support of method
chaining) but the truth was never revealed...

Chaining is the reason.

a.please.do.this

instead of:

a.please
a.do
a.this
;-)

Cheers

robert

--
Daryl Richter
Platform Author & Director of Technology

(( Brandywine Asset Management )
( "Expanding the Science of Global Investing" )
( http://www.brandywine.com ))
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top