Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialJeff Lange
8,788 PointsYield runs a block, but I don't understand what block this yield is running. And more! Come on in if you like to teach!
I understand that "yield" runs a "block" of code sharing the same name as the method containing "yield." However, in this particular code (which allows you to write a speech in lines and then print to the screen) I don't understand what the "def each" method is doing on lines 26-28.
Can someone explain this in detail? And I mean slow: as if I have brain damage. I know this method is making it possible to print each line consecutively, but I have absolutely no clue about how it's doing that.
Relevant questions (mostly center on lines 26-28 near the bottom, the def each method):
- why is there &block? I don't see a block.call anywhere? (line 26)
- isn't .each already defined by default in Ruby? Did we redefine it? (lines 26-28)
- how do the pipes || work? Why did we have to put "line" in the pipes? (lines 26-28)
- how is yield working properly here if we didn't create a separate block that shares the name of this method? I thought that's how yield worked: it ran the code from a block that shares the name of method yield is in. (lines 26-28)
- shouldn't it be for each line we "puts" that line rather than yield it? Why did we write the code that prints the speech to the screen down on lines 36-38 instead of including it here?
And finally the code itself:
class Speech
def initialize
print "What is the speech name? "
@title = gets.chomp
@lines = []
while add_line
puts "Line added."
end
end
def title
@title
end
def add_line
puts "Add a line: (blank line to exit)"
line = gets.chomp
if line.length > 0
@lines.push line
return line
else
return nil
end
end
def each(&block)
@lines.each { |line| yield line}
end
end
speech = Speech.new
puts "#{speech.title.upcase}\n\n"
speech.each do |line|
puts "#{line}"
end
Hopefully there are some natural teachers out here in the forum that love answering questions--I'm certainly full of them! :)
1 Answer
Kang-Kyu Lee
52,045 PointsI'm positive that block.call
is the same thing to yield
here. And yes, each method of Speech class redefines (overrides) built-in each
method. In this case looks like, in order to run the block only for each of @lines
of Speech object.
Jeff Lange
8,788 PointsJeff Lange
8,788 PointsThanks for responding!
I still don't understand why &block had to be put in, as yield never needed &block in the treehouse tutorial videos.
Ok, so you can override Ruby's built-in methods. Interesting!
Any other thoughts from anyone? I still don't really get what's going on with this code.
Kang-Kyu Lee
52,045 PointsKang-Kyu Lee
52,045 PointsHi Jeff, a block can take parameters. kinda hard to explain. I think there's another person will explain it more comprehensively or you may look up any ruby language books. Putting
&
to block coverts it into a Proc so it can take Proc instance methods (likecall
) in the method which receives that. blocks are not objects.