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 trial

Ruby Ruby Blocks Blocks Practice Build a Monster Class: Part 4

David Bell
David Bell
16,997 Points

Is block the same as block_given? in an if statement?

In completing the corresponding code challenge for Build a Monster Class part 4, I blanked and just put

yield self if block

This actually passed the challenge, but I'm just wondering what I actually did here!

So, is it the case that block and block_given? are functionally the same when used in an if statement? block itself isn't a boolean object (so far as I can tell)... so is ruby taking the parameter, in an if statement, as an ... existence check?

If that is a functionally valid case, is it otherwise actually bad form?

2 Answers

Daniel Cunningham
Daniel Cunningham
21,109 Points

That's a great find! I didn't know that would work, but I took some time to explore it, so here what I can gather... <br> <br>

In the hide, scare, or other methods that were defined in the "monster class", if you were to add "puts block.class" to the code, you would find that the block class is Proc. <br> <br>

If you were to test one of these classes in an if statement, you could do something like this: <br> <br> if Proc.new <br> puts "yes" <br> else <br> puts "no" <br> end <br> <br>

This evaluates to true. Conversely, it will evaulate to false if you use "Not" (!Proc.new). For whatever reason, Proc appears to have a "truthy" value when tested much the same way any integer would evaluate as true. <br><br>

It appears that, in the absence of a boolean equation, most inputs that have values (that are not nil or false of course) will result in true. You should definitely test other values for yourself as you program things, but that's been my finding so far. <br><br>

For the purposes of this challenge, I tried breaking the code. If a block were NOT given while running the method, evaluating block.class results in NilClass which always returns as false in boolean statements. So if a block is given, then block.class is Proc and returns true while the absence of a block will result in block.class being a Nil (which returns false.) <br> <br>

Using "yield self if block" in this case will work because it returns "truthy" and "falsey" values under the necessary circumstances, but if you want to be certain that you are getting a true and false return based on the presence of a block, it is probably a best practice to stick with block_given? <br> <br>

So David, I think this is a very long winded way of saying "Yes, it is an existence check", but I hope that helps!

David Bell
David Bell
16,997 Points

That's a great answer, thanks!

Polly Sileo
Polly Sileo
3,696 Points

I had the same question. I have asked around and it seems that purposely there are many ways to accomplish the same thing in Ruby. These both work and it just comes down to coding style. I think block is giving a boolean so here there is no difference, there would be times when it wouldn't be returning a boolean and you would have to use block_given? so it's important to know that as an option too.

David Bell
David Bell
16,997 Points

Hey very cool! Its neat that Ruby can allow this!