Reputation: 746
As a Ruby newbie, it's confusing to me why it would ever be beneficial to yield self
within a method definition. I've come across this functionality in a number of tutorials as being something that is helpful -- it makes perfect sense to me how this works, but I don't understand why you'd ever use it.
Let's say I have the following code:
class Dog
attr_accessor :breed
def initialize
@breed = "Westie"
end
def bark
puts "Woof!"
yield self if block_given?
end
end
fido = Dog.new
fido.bark do |d|
puts "Bark, bark, bark!"
puts d.breed
end
So yeah, via yield self
, I now have access to the instance of the Dog
class within the block that I am yielding too.
But, even if I don't yield self
, I would still have access to that instance, right? In other words, wouldn't the code below work exactly the same as the code above?
class Dog
attr_accessor :breed
def initialize
@breed = "Westie"
end
def bark
puts "Woof!"
yield
end
end
fido = Dog.new
fido.bark do
puts "Bark, bark, bark!"
puts fido.breed
end
Note that in the second code sample, I'm not calling yield self
.
I'm clearly missing the utility here.
Upvotes: 3
Views: 870
Reputation: 66263
The second example works because of the specific circumstances where you have a local variable referring to the the Dog
. As an alternative consider what happens if using an anonymous instance:
Dog.new.bark do
puts "Bark, bark, bark!"
# what goes here?? puts ????.breed
end
or maybe you want to declare your block somewhere else and pass it in e.g.
loud = lambda { |dog| puts "A #{dog.breed} doing some LOUD YAPPING" }
puts d.bark(&loud)
so essentially setting up with yield self
gives flexibility in how your code can be used.
Upvotes: 5
Reputation: 239311
Your examples are pretty simple, and there's no obvious use for yield self
in them.
There are cases when it is useful though, the same way that tap
is useful: It allows you to define and use a value without introducing a variable in the local scope.
A (admittedly very contrived) example would be:
Dog.new.bark do |d|
puts d.breed
end
Upvotes: 3