Explaination of a bit of code

D

Dave Lenhardt

Hey, another question. This is kinda putting several concepts together
that i understand but the code is throwing me for some reason:

class Periods
def each
yield "Classical"
yield "Jazz"
yield "Rock"
end
end


periods = Periods.new
for genre in periods
print genre, " "
end

produces:
Classical Jazz Rock

So a simple for..in loop which is the same as using the .each for an
array/Hash, etc.

I guess I am having trouble thinking how this would work out. Each is
suppose to go through a set of items. however, where are the items? I
see three strings but they are used in yield statements. How is this
method actually working?
 
S

Sebastian Hungerecker

Dave said:
Each is suppose to go through a set of items.

each is supposed to whatever it has been defined to do. It's not special.
It's not different from any other method. You can define it to do whatever you
want. And in this case it is defined to yield three strings so that's what it
does.
 
D

Dave Lenhardt

And while we are at little samples of code...

if false
a = 1
end
3.times {|i| a = i }


a --> 2


I was looking at an example and was a bit confused why variable a got 2.
I undrestand the basic idea of this example (as long as a is defined
somewhere, evne if it's value is never reached, it exists), but why 2?
Is the times method going from 0 to X-1 where X is the number in
X.times?
 
T

Thomas B.

Dave said:
I guess I am having trouble thinking how this would work out. Each is
suppose to go through a set of items. however, where are the items? I
see three strings but they are used in yield statements. How is this
method actually working?

The method each is working just as you programme it. For Arrays (and
Enumerables, in general) it calls the passed block with each element of
the object (self) in turn, so in some useless pseudocode, Array#each
works like this:
for each element of self in e
yield(e)
end
Now you can see that your own each works just like
["Classical","Jazz","Rock"].each{|e| yield(e)}
So, your Periods::new works like the array ["Classical","Jazz","Rock"]
itself. Only your object is a dummy array - it does not read the
elements from any kind of set or anything, it is just hardcoded to call
yield with these three strings. But from outside you cannot tell your
Period::new from ["Classical","Jazz","Rock"], they just behave in the
same way when we call the method each on them. And that's why the for
loop sees your object as if it was the array of the three strings.

TPR.
 
S

Sebastian Hungerecker

Dave said:
Is the times method going from 0 to X-1 where X is the number in
X.times?

Yes.
Try this: 3.times {|i| p i}
Prints:
0
1
2

HTH,
Sebastian
 
D

Dave Lenhardt

Thanks all.

I should note that these are not my programs but snippets from a book
(Programming Guide to Ruby) that I am trying to make sure I understand.

Here's another snippet I am wondering on:

catch :)done) do
while line = gets
throw :done unless fields = line.split(/\t/)
songlist.add(Song.new(*fields))
end
songlist.play
end

So, according to the book, it's looking for badly formatted strings. If
there is a badly formatted string, the throw clause is invoked. Now,
the question is, where does the throw clause go. I see that catch
:)done) is right there, but how does the throw clause "find" the catch
clause.

In other words, I am trying to understand howt his works compared to...

while line = gets
throw :done unless fields = line.split (/\t/)
songlist.add(Song.new(*fields))
end
end

catch :done
#handle issues
end
 
B

Brian Candler

Dave said:
Here's another snippet I am wondering on:

catch :)done) do
while line = gets
throw :done unless fields = line.split(/\t/)
songlist.add(Song.new(*fields))
end
songlist.play
end

So, according to the book, it's looking for badly formatted strings. If
there is a badly formatted string, the throw clause is invoked. Now,
the question is, where does the throw clause go.

The throw has to be *inside* a corresponding catch block, and it drops
you to the end of the catch block.

You can also give a value alongside the throw; if so, this is the value
"returned" by the catch block itself.

ans = catch:)hello) do
throw :hello, 2
puts "Never reached"
3
end
p ans # 2
I see that catch
:)done) is right there, but how does the throw clause "find" the catch
clause.

It's pretty much the same as an exception. The interpreter winds back
the stack looking for a matching 'catch' block.
In other words, I am trying to understand howt his works compared to...

while line = gets
throw :done unless fields = line.split (/\t/)
songlist.add(Song.new(*fields))
end
end

catch :done
#handle issues
end

That won't work, because when the throw executes, there is no enclosing
matching catch block.
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top