Recientemente comencé a programar en Ruby, y estoy buscando manejo de excepciones.
Me preguntaba si ensure
era el equivalente de Ruby finally
en C #? Debería tener:
file = File.open("myFile.txt", "w")
begin
file << "#{content} \n"
rescue
#handle the error here
ensure
file.close unless file.nil?
end
o debería hacer esto?
#store the file
file = File.open("myFile.txt", "w")
begin
file << "#{content} \n"
file.close
rescue
#handle the error here
ensure
file.close unless file.nil?
end
¿ ensure
Me llaman sin importar qué, incluso si no se genera una excepción?
ruby-on-rails
ruby
exception
exception-handling
error-handling
Lloyd Powell
fuente
fuente
begin
bloque.Respuestas:
Sí,
ensure
asegura que el código siempre se evalúa. Por eso se llamaensure
. Por lo tanto, es equivalente a Java y C #finally
.El flujo general de
begin
/rescue
/else
/ensure
/ seend
ve así:Puedes dejar afuera
rescue
,ensure
oelse
. También puede omitir las variables, en cuyo caso no podrá inspeccionar la excepción en su código de manejo de excepciones. (Bueno, siempre puede usar la variable de excepción global para acceder a la última excepción que se generó, pero eso es un poco confuso). Y puede omitir la clase de excepción, en cuyo caso se detectarán todas las excepciones que heredenStandardError
. (Tenga en cuenta que esto no significa que todas las excepciones son capturadas, porque hay excepciones que son instancias deException
pero noStandardError
. Excepciones mayoría muy graves que ponen en peligro la integridad del programa, tales comoSystemStackError
,NoMemoryError
,SecurityError
,NotImplementedError
,LoadError
,SyntaxError
,ScriptError
,Interrupt
,SignalException
oSystemExit
)Algunos bloques forman bloques de excepción implícitos. Por ejemplo, las definiciones de métodos son implícitamente también bloques de excepción, por lo que en lugar de escribir
solo escribes
o
Lo mismo se aplica a las
class
definiciones ymodule
definiciones.Sin embargo, en el caso específico sobre el que está preguntando, en realidad hay una expresión mucho mejor. En general, cuando trabajas con algún recurso que necesitas limpiar al final, lo haces pasando un bloque a un método que hace toda la limpieza por ti. Es similar a un
using
bloque en C #, excepto que Ruby es lo suficientemente poderoso como para no tener que esperar a que los sumos sacerdotes de Microsoft bajen de la montaña y cambien gentilmente su compilador por usted. En Ruby, puedes implementarlo tú mismo:Y qué sabes: esto ya está disponible en la biblioteca principal como
File.open
. Pero es un patrón general que también puede usar en su propio código, para implementar cualquier tipo de limpieza de recursos (a lausing
en C #) o transacciones o cualquier otra cosa que pueda pensar.El único caso donde esto no funciona, si la adquisición y la liberación del recurso se distribuyen en diferentes partes del programa. Pero si está localizado, como en su ejemplo, entonces puede usar fácilmente estos bloques de recursos.
Por cierto: en C # moderno, en
using
realidad es superfluo, porque puede implementar bloques de recursos de estilo Ruby usted mismo:fuente
ensure
declaraciones se ejecutan en último lugar, no son el valor de retorno.ensure
llaman sin importar qué".Para su información, incluso si se vuelve a generar una excepción en la
rescue
sección, elensure
bloque se ejecutará antes de que la ejecución del código continúe con el siguiente controlador de excepciones. Por ejemplo:fuente
Si desea asegurarse de que un archivo esté cerrado, debe usar la forma de bloque de
File.open
:fuente
Sí,
ensure
se llama en cualquier circunstancia. Para obtener más información, consulte " Excepciones, capturas y lanzamientos " del libro de programación Ruby y busque "garantizar".fuente
Sí,
ensure
ASEGURA que se ejecuta siempre, por lo que no necesitafile.close
elbegin
bloque.Por cierto, una buena forma de probar es hacer:
Puede comprobar si se imprimirá "========= dentro del bloque de seguridad" cuando haya una excepción. Luego, puede comentar la declaración que genera el error y ver si la
ensure
declaración se ejecuta al ver si se imprime algo.fuente
Por eso necesitamos
ensure
:fuente
Sí,
ensure
comofinally
garantiza que el bloque se ejecutará . Esto es muy útil para asegurarse de que los recursos críticos estén protegidos, por ejemplo, cerrar un identificador de archivo por error o liberar un mutex.fuente
File.open
parte NO está dentro del bloque de inicio- garantía . Solofile.close
es pero no es suficiente.