I have been practicing Ruby and believe it or not the hardest part for
me to understand (so far) is the concept of using blocks, why used them
and how to use them.
For instance, I know I don’t fully understand blocks but why would you
use a block in the following situation.
text = “Some Text”
File.open(‘test_file.txt’, ‘a+’) do |file|
file.write(text)
end
Why not just …?
text = “Some Text”
file = File.open(‘test_file1.txt’, ‘a+’)
file.write(text)
…why use a block instead?
1-What would be a good rule of thumb to know when to use blocks?
2-What would be the easiest way to understand block?
3-Can someone be so kind and explain block a little bit?
Thanks a lot for all of your help!
Learning a lot in this forum. Awesome people!
I have been practicing Ruby and believe it or not the hardest part for
me to understand (so far) is the concept of using blocks, why used them
and how to use them.
There are several benefits and use cases for using blocks.
text = “Some Text”
file = File.open(‘test_file1.txt’, ‘a+’)
file.write(text)
…why use a block instead?
This is quite straightforward: in this situation the use case is that
you want to ensure that something happens before and after the block
code. In this case, the File#open method opens the file, then calls
the block and then ensures that the file is closed, even in the face
of an exception within the block.
So, first use case: when you want code executed around code that is
not under your control.
Another use case is when you provide a generic functionality that can
applied to many situations, but you want to leave the exact detailed
behavior to the client code. For example, the Enumerable#each method
provides its clients with the capability of traversing an enumerable
instance, doing something with each element one at a time. What you do
with the element is responsibility of the client code, so the each
method just accepts a block to achieve that.
Hope this helps and I hope the concept clicks soon, because it’s one
of the things that make Ruby so wonderful.
This is quite straightforward: in this situation the use case is that
you want to ensure that something happens before and after the block
code. In this case, the File#open method opens the file, then calls
the block and then ensures that the file is closed, even in the face
of an exception within the block.
So the main difference in this case is that by using block the file will
be closed by itself and if I use the second method I would need to
manually close it?
text = “Some Text”
File.open(‘test_file.txt’, ‘a+’) do |file|
file.write(text)
end
Why not just …?
text = “Some Text”
file = File.open(‘test_file1.txt’, ‘a+’)
file.write(text)
…why use a block instead?
To make the code robust and ensure the resource is freed under all
circumstances (especially exceptions, but also control flow which uses
break, return or throw).
This is quite straightforward: in this situation the use case is that
you want to ensure that something happens before and after the block
code. In this case, the File#open method opens the file, then calls
the block and then ensures that the file is closed, even in the face
of an exception within the block.
Shameless self advertizing: More explanations here:
So, first use case: when you want code executed around code that is
not under your control.
Yep, a block is just an anonymous function with a nice invocation
syntax. In other programming languages one sometimes uses template
method pattern in such situations
the File.open block is really useful, but probably not the easiest way
to understand how to use blocks…
think about the Array.each block - when you call Array.each, you then
define a block of code that will be passed each entry in the array as an
argument (which you name inside the bars ||)
array = [“Tom”, “Dick”, “Harry”]
array.each do |name|
puts "Hi " + name
end
=> Hi Tom
Hi Dick
Hi Harry
…or…
array.each do |name|
puts "Hi " + name unless name == “Dick”
end
=> Hi Tom
Hi Harry
note that you can usually also use curly braces {} instead of the ‘do’
and ‘end’ keywords…