Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Yes, <code>ensure</code> ensures that the code is always evaluated. That's why it's called <code>ensure</code>. So, it is equivalent to Java's and C#'s <code>finally</code>.</p> <p>The general flow of <code>begin</code>/<code>rescue</code>/<code>else</code>/<code>ensure</code>/<code>end</code> looks like this:</p> <pre><code>begin # something which might raise an exception rescue SomeExceptionClass =&gt; some_variable # code that deals with some exception rescue SomeOtherException =&gt; some_other_variable # code that deals with some other exception else # code that runs only if *no* exception was raised ensure # ensure that this code always runs, no matter what # does not change the final value of the block end </code></pre> <p>You can leave out <code>rescue</code>, <code>ensure</code> or <code>else</code>. You can also leave out the variables in which case you won't be able to inspect the exception in your exception handling code. (Well, you can always use the global exception variable to access the last exception that was raised, but that's a little bit hacky.) And you can leave out the exception class, in which case all exceptions that inherit from <code>StandardError</code> will be caught. (Please note that this does not mean that <em>all</em> exceptions are caught, because there are exceptions which are instances of <code>Exception</code> but not <code>StandardError</code>. Mostly very severe exceptions that compromise the integrity of the program such as <code>SystemStackError</code>, <code>NoMemoryError</code>, <code>SecurityError</code>, <code>NotImplementedError</code>, <code>LoadError</code>, <code>SyntaxError</code>, <code>ScriptError</code>, <code>Interrupt</code>, <code>SignalException</code> or <code>SystemExit</code>.)</p> <p>Some blocks form implicit exception blocks. For example, method definitions are implicitly also exception blocks, so instead of writing</p> <pre><code>def foo begin # ... rescue # ... end end </code></pre> <p>you write just</p> <pre><code>def foo # ... rescue # ... end </code></pre> <p>or</p> <pre><code>def foo # ... ensure # ... end </code></pre> <p>The same applies to <code>class</code> definitions and <code>module</code> definitions.</p> <p>However, in the specific case you are asking about, there is actually a much better idiom. In general, when you work with some resource which you need to clean up at the end, you do that by passing a block to a method which does all the cleanup for you. It's similar to a <code>using</code> block in C#, except that Ruby is actually powerful enough that you don't have to wait for the high priests of Microsoft to come down from the mountain and graciously change their compiler for you. In Ruby, you can just implement it yourself:</p> <pre><code># This is what you want to do: File.open('myFile.txt', 'w') do |file| file.puts content end # And this is how you might implement it: def File.open(filename, mode='r', perm=nil, opt=nil) yield filehandle = new(filename, mode, perm, opt) ensure filehandle&amp;.close end </code></pre> <p>And what do you know: this is <em>already</em> available in the core library as <code>File.open</code>. But it is a general pattern that you can use in your own code as well, for implementing any kind of resource cleanup (à la <code>using</code> in C#) or transactions or whatever else you might think of.</p> <p>The only case where this doesn't work, if acquiring and releasing the resource are distributed over different parts of the program. But if it is localized, as in your example, then you can easily use these resource blocks.</p> <hr> <p>BTW: in modern C#, <code>using</code> is actually superfluous, because you can implement Ruby-style resource blocks yourself:</p> <pre><code>class File { static T open&lt;T&gt;(string filename, string mode, Func&lt;File, T&gt; block) { var handle = new File(filename, mode); try { return block(handle); } finally { handle.Dispose(); } } } // Usage: File.open("myFile.txt", "w", (file) =&gt; { file.WriteLine(contents); }); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload