I think the technique is important to have in your vocabulary, but I think the examples given are a weak sell.
In the example given, I would have preferred to extract to a method—-what if I want to load the config from somewhere else? And perhaps the specific of strip comments itself could have been extracted to a more-semantically-aptly named post-processing method.
I see the argument that when extracted to a function, that you don’t need to go hunting for it. But if we look at the example with the block, I still see a bunch of detail about how to load the config, and then several lines using it. What’s more important in that context—-the specifics of the loading of config, or the specifics of how requests are formed using the loaded config?
The fact that you need to explain what’s happening with comments is a smell. Properly named variables and methods would obviate the need for the comments and would introduce semantic meaning thru names.
I think blocks are useful when you are referencing a lot of local variables and also have fairly localized meaning within the method. For example, you can write a block to capture a bunch of values for logging context—-then you can call that block in every log line to get a logging context based on current method state. It totally beats extracting a logging context method that consumes many variables and is unlikely to be reused outside of the calling method, and yet you get delayed evaluation and single point of definition for it.
So yes to the pattern, but needs a better example.
> what if I want to load the config from somewhere else?
There are DRY and WET principles. We can argue which one of them is better, but to move something used exactly once to a method just due to an anxiety you can need it again seems to me a little bit too much. I move things into functions that are called once, but iff it makes my code clearer. It can happen when code is already complicated and long.
The block allows you to localize the code, and refactoring it into a separate function will be trivial. You need not to check if all the variables are temporary, you just see the block, copy/paste it, add a function header, and then add function call at the place where the block was before. No thinking and no research is needed. Veni, vidi, vici.
> The fact that you need to explain what’s happening with comments is a smell.
It is an example for the article taken out of a context. You'd better comment it for the sake of your readers.
> I think blocks are useful when you are referencing a lot of local variables and also have fairly localized meaning within the method.
I do it each time I need a temporary variable. I hate variables that exist but are not used, they make it harder to read the code, you need to track temporaries through all the code to confirm that they are temporaries. So even if I have just two local variables (not "a lot of") and one of them is temporary, I'd probably localize the temporary one even further into its own block. What really matters is a code readability: if the function has just three lines, it doesn't matter, but it becomes really ugly if a lifetime of a variable overshoots its usefulness for 20 lines of a dense code.
The other thing is mutability/immutability: you can drop mutability when returning a value from a block. Mutability makes reasoning harder, so dropping it when you don't need it anymore is a noble deed. It can and will reduce the complexity of reading the code. You'll thank yourself many times later, when faced with necessity to reread your own code.
There is a code and there is the process of devising the code. You cannot understand the former without reverse engineering the latter. So, when you write code, the more of your intentions are encoded somehow in your code, the easier it will be to read your code. If you create temporary variables just to parse config with the final goal to get the parsed config in a variable, then you'd better encode it. You can add comments, like "we need to parse config and for that we need three temporary variables", or you can localize those three temporary variables in a block.