{"id":314,"date":"2023-05-15T08:23:00","date_gmt":"2023-05-15T08:23:00","guid":{"rendered":"https:\/\/jorgeturiel.es\/?p=314"},"modified":"2023-08-11T21:13:13","modified_gmt":"2023-08-11T20:13:13","slug":"introduccion-al-lenguaje-pascal-moderno-para-programadores-parte-5","status":"publish","type":"post","link":"https:\/\/jorgeturiel.es\/?p=314","title":{"rendered":"Introducci\u00f3n al lenguaje Pascal moderno para programadores (Parte 5)"},"content":{"rendered":"\n<p id=\"block-5521090e-ab25-4c7d-8ff9-7b06a21f4a1b\">Continuamos con la introducci\u00f3n al lenguaje Pascal Moderno.<\/p>\n\n\n\n<p id=\"block-404f08e6-e309-4eb0-84cf-cdf990136039\">Esta entrada es una traducci\u00f3n al espa\u00f1ol, del texto <a rel=\"noreferrer noopener\" href=\"https:\/\/castle-engine.io\/modern_pascal\" target=\"_blank\">original<\/a> escrito por Michalis Kamburelis.<\/p>\n\n\n\n<p id=\"block-5521090e-ab25-4c7d-8ff9-7b06a21f4a1b\">Continuamos con la introducci\u00f3n al lenguaje Pascal Moderno.<\/p>\n\n\n\n<p id=\"block-5521090e-ab25-4c7d-8ff9-7b06a21f4a1b\">Esta entrada es una traducci\u00f3n al espa\u00f1ol, del texto <a rel=\"noreferrer noopener\" href=\"https:\/\/castle-engine.io\/modern_pascal\" target=\"_blank\">original<\/a> escrito por Michalis Kamburelis.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Excepciones<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Descripci\u00f3n general<\/h3>\n\n\n\n<p>Las excepciones permiten interrumpir la ejecuci\u00f3n normal del c\u00f3digo.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>En cualquier punto dentro del programa, puede generar una excepci\u00f3n utilizando la palabra clave <em>raise<\/em>.En efecto, las l\u00edneas de c\u00f3digo que siguen a la llamada aumentar\u2026 no se ejecutar\u00e1n<\/li>\n\n\n\n<li>Se puede capturar una excepci\u00f3n usando una construcci\u00f3n try\u2026except\u2026end. Detectar una excepci\u00f3n significa que de alguna manera \u00ablidias\u00bb con la excepci\u00f3n, y el siguiente c\u00f3digo deber\u00eda ejecutarse como de costumbre, la excepci\u00f3n ya no se propaga hacia arriba.\n<ul class=\"wp-block-list\">\n<li>Nota: Si se genera una excepci\u00f3n pero nunca se detecta, har\u00e1 que toda la aplicaci\u00f3n se detenga con un error. Pero en las aplicaciones LCL, las excepciones siempre se detectan alrededor de los eventos (y provocan el cuadro de di\u00e1logo LCL) si no las detecta antes.<\/li>\n\n\n\n<li>En las aplicaciones de Castle Game Engine que usan CastleWindow, de manera similar, siempre detectamos excepciones en torno a sus eventos (y mostramos el cuadro de di\u00e1logo adecuado).<\/li>\n\n\n\n<li>Por lo tanto, no es tan f\u00e1cil hacer una excepci\u00f3n que no se detecte en ninguna parte (no se detecte en su c\u00f3digo, c\u00f3digo LCL, c\u00f3digo CGE\u2026).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Si bien una excepci\u00f3n interrumpe la ejecuci\u00f3n, puede usar la construcci\u00f3n try\u2026finally\u2026end para ejecutar alg\u00fan c\u00f3digo siempre, incluso si el c\u00f3digo fue interrumpido por una excepci\u00f3n. <\/li>\n\n\n\n<li>La construcci\u00f3n try\u2026finally\u2026end tambi\u00e9n funciona cuando el c\u00f3digo es interrumpido por las palabras clave Break, Continue o Exit. El punto es ejecutar siempre el c\u00f3digo en la secci\u00f3n finalmente.<\/li>\n<\/ul>\n\n\n\n<p>Una \u00abexcepci\u00f3n\u00bb es, en general, cualquier instancia de clase.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>El compilador no impone ninguna clase en particular. Solo debe llamar a raise XXX donde XXX es una instancia de cualquier clase. Cualquier clase (por lo tanto, cualquier cosa que descienda de TObject) est\u00e1 bien. <\/li>\n\n\n\n<li>Es una convenci\u00f3n est\u00e1ndar que las clases de excepci\u00f3n desciendan de una clase de excepci\u00f3n especial. La clase Exception extiende TObject, agregando una propiedad Message de cadena y un constructor para configurar f\u00e1cilmente esta propiedad. Todas las excepciones generadas por la biblioteca est\u00e1ndar descienden de Exception. Recomendamos seguir esta convenci\u00f3n. <\/li>\n\n\n\n<li>Las clases de excepci\u00f3n (por convenci\u00f3n) tienen nombres que comienzan con E, no con T. Como ESomethingBadHappened.<\/li>\n\n\n\n<li>El compilador liberar\u00e1 autom\u00e1ticamente el objeto de excepci\u00f3n cuando se maneje. No lo liberes t\u00fa mismo. <\/li>\n\n\n\n<li>En la mayor\u00eda de los casos, simplemente construyes el objeto al mismo tiempo que llamas a raise, como raise EAlgo MalOcurrido.Crear(&#8216;Descripci\u00f3n de lo malo que sucedi\u00f3&#8217;).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Levantamiento, elevaci\u00f3n, propagaci\u00f3n (Raising)<\/h2>\n\n\n\n<p>Si desea generar su propia excepci\u00f3n, declararla y llame a la elevaci\u00f3n\u2026 cuando corresponda:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  EInvalidParameter = class(Exception);\n\nfunction ReadParameter: String;\nbegin\n  Result := Readln;\n  if Pos(' ', Result) &lt;&gt; 0 then\n    raise EInvalidParameter.Create('Invalid parameter, space is not allowed');\nend;<\/pre><\/div>\n\n\n\n<p>Tenga en cuenta que la expresi\u00f3n que sigue al aumento debe ser una instancia de clase v\u00e1lida para aumentar. Casi siempre crear\u00e1 la instancia de excepci\u00f3n aqu\u00ed. <\/p>\n\n\n\n<p>Tambi\u00e9n puede usar el constructor CreateFmt, que es un atajo c\u00f3modo para Create(Format(MessageFormat, MessageArguments)). Esta es una forma com\u00fan de proporcionar m\u00e1s informaci\u00f3n al mensaje de excepci\u00f3n. Podemos mejorar el ejemplo anterior as\u00ed:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">type\n  EInvalidParameter = class(Exception);\n\nfunction ReadParameter: String;\nbegin\n  Result := Readln;\n  if Pos(' ', Result) &lt;&gt; 0 then\n    raise EInvalidParameter.CreateFmt('Invalid parameter %s, space is not allowed', [Result]);\nend;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Atrapando<\/h2>\n\n\n\n<p>Puede detectar una excepci\u00f3n como esta:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">var\n  Parameter1, Parameter2, Parameter3: String;\nbegin\n  try\n    Writeln('Input 1st parameter:');\n    Parameter1 := ReadParameter;\n    Writeln('Input 2nd parameter:');\n    Parameter2 := ReadParameter;\n    Writeln('Input 3rd parameter:');\n    Parameter3 := ReadParameter;\n  except\n    \/\/ capture EInvalidParameter raised by one of the above ReadParameter calls\n    on EInvalidParameter do\n      Writeln('EInvalidParameter exception occurred');\n  end;\nend;<\/pre><\/div>\n\n\n\n<p>Para mejorar el ejemplo anterior, podemos declarar el nombre de la instancia de excepci\u00f3n (usaremos E en el ejemplo). De esta manera podemos imprimir el mensaje de excepci\u00f3n:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">try\n...\nexcept\n  on E: EInvalidParameter do\n    Writeln('EInvalidParameter exception occurred with message: ' + E.Message);\nend;<\/pre><\/div>\n\n\n\n<p>O tambi\u00e9n podemos comprobar clases de excepciones<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">try\n...\nexcept\n  on E: EInvalidParameter do\n    Writeln('EInvalidParameter exception occurred with message: ' + E.Message);\n  on E: ESomeOtherException do\n    Writeln('ESomeOtherException exception occurred with message: ' + E.Message);\nend;<\/pre><\/div>\n\n\n\n<p>Tambi\u00e9n puede reaccionar a cualquier excepci\u00f3n generada, si no usa ninguna expresi\u00f3n:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">try\n...\nexcept\n  Writeln('Warning: Some exception occurred');\nend;\n\/\/ WARNING: DO NOT FOLLOW THIS EXAMPLE WITHOUT READING A WARNING BELOW\n\/\/ ABOUT \"CAPTURING ALL EXCEPTIONS<\/pre><\/div>\n\n\n\n<p>En general, solo debe capturar excepciones de una clase espec\u00edfica, que se\u00f1alan un problema particular con el que sabe qu\u00e9 hacer. Tenga cuidado con la captura de excepciones de tipo general (como la captura de cualquier excepci\u00f3n o cualquier TObject), ya que puede capturar f\u00e1cilmente demasiadas y luego causar problemas al depurar otros problemas. <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u00bfLa excepci\u00f3n indica un problema en la entrada del usuario?<\/li>\n\n\n\n<li> Entonces deber\u00edas reportarlo al usuario.<\/li>\n\n\n\n<li>\u00bfLa excepci\u00f3n indica un error en su c\u00f3digo? Luego, debe corregir el c\u00f3digo para evitar que ocurra la excepci\u00f3n.<\/li>\n<\/ul>\n\n\n\n<p>Otra forma de capturar todas las excepciones es usar:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">try\n...\nexcept\n  on E: TObject do\n    Writeln('Warning: Some exception occurred');\nend;\n\/\/ WARNING: DO NOT FOLLOW THIS EXAMPLE WITHOUT READING A WARNING ABOVE\n\/\/ ABOUT \"CAPTURING ALL EXCEPTIONS\"\n\n<\/pre><\/div>\n\n\n\n<p>Aunque normalmente es suficiente para capturar Exception:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">try\n...\nexcept\n  on E: Exception do\n    Writeln('Warning: Some exception occurred: ' + E.ClassName + ', message: ' + E.Message);\nend;\n\/\/ WARNING: DO NOT FOLLOW THIS EXAMPLE WITHOUT READING A WARNING ABOVE\n\/\/ ABOUT \"CAPTURING ALL EXCEPTIONS\"<\/pre><\/div>\n\n\n\n<p>Puede \u00abvolver a generar\u00bb la excepci\u00f3n en el bloque excepto\u2026 final, si as\u00ed lo decide. Puede hacer aumentar E si la instancia de excepci\u00f3n es E, tambi\u00e9n puede usar aumentar sin par\u00e1metros. Por ejemplo:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">try\n...\nexcept\n  on E: EInvalidSoundFile do\n  begin\n    if E.InvalidUrl = 'http:\/\/example.com\/blablah.wav' then\n      Writeln('Warning: loading http:\/\/example.com\/blablah.wav failed, ignore it')\n    else\n      raise;\n  end;\nend;<\/pre><\/div>\n\n\n\n<p>Tenga en cuenta que, aunque la excepci\u00f3n es una instancia de un objeto, nunca debe liberarlo manualmente despu\u00e9s de generarlo. El compilador generar\u00e1 el c\u00f3digo adecuado que se asegura de liberar el objeto de excepci\u00f3n una vez que se maneja.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Finalmente (hacer cosas sin importar si ocurri\u00f3 una excepci\u00f3n)<\/h2>\n\n\n\n<p>A menudo usas try .. La forma de escribirlo se ve as\u00ed:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">procedure MyProcedure;\nvar\n  MyInstance: TMyClass;\nbegin\n  MyInstance := TMyClass.Create;\n  try\n    MyInstance.DoSomething;\n    MyInstance.DoSomethingElse;\n  finally\n    FreeAndNil(MyInstance);\n  end;\nend;<\/pre><\/div>\n\n\n\n<p>Esto siempre funciona de manera confiable y no provoca p\u00e9rdidas de memoria, incluso si MyInstance.DoSomething o MyInstance.DoSomethingElse generan una excepci\u00f3n.<\/p>\n\n\n\n<p>Tenga en cuenta que esto tiene en cuenta que las variables locales, como MyInstance arriba, tienen valores indefinidos (pueden contener \u00abbasura de memoria\u00bb aleatoria) antes de la primera asignaci\u00f3n. Es decir, escribir algo como esto no ser\u00eda v\u00e1lido:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">\/\/ INCORRECT EXAMPLE:\nprocedure MyProcedure;\nvar\n  MyInstance: TMyClass;\nbegin\n  try\n    CallSomeOtherProcedure;\n    MyInstance := TMyClass.Create;\n    MyInstance.DoSomething;\n    MyInstance.DoSomethingElse;\n  finally\n    FreeAndNil(MyInstance);\n  end;\nend;<\/pre><\/div>\n\n\n\n<p>El ejemplo anterior no es v\u00e1lido: si ocurre una excepci\u00f3n dentro de TMyClass.Create (un constructor tambi\u00e9n puede generar una excepci\u00f3n), o dentro de CallSomeOtherProcedure, entonces la variable MyInstance no se inicializa. Llamar a FreeAndNil(MyInstance) intentar\u00e1 llamar al destructor de MyInstance, que probablemente se bloquee con una infracci\u00f3n de acceso (falla de segmentaci\u00f3n). En efecto, una excepci\u00f3n provoca otra excepci\u00f3n, lo que har\u00e1 que el informe de errores no sea muy \u00fatil: no ver\u00e1 el mensaje de la excepci\u00f3n original.<\/p>\n\n\n\n<p>A veces se justifica arreglar el c\u00f3digo anterior inicializando primero todas las variables locales a cero (en las que llamar a FreeAndNil es seguro y no har\u00e1 nada). Esto tiene sentido si libera muchas instancias de clase. As\u00ed que los dos ejemplos de c\u00f3digo a continuaci\u00f3n funcionan igual de bien:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">procedure MyProcedure;\nvar\n  MyInstance1: TMyClass1;\n  MyInstance2: TMyClass2;\n  MyInstance3: TMyClass3;\nbegin\n  MyInstance1 := TMyClass1.Create;\n  try\n    MyInstance1.DoSomething;\n\n    MyInstance2 := TMyClass2.Create;\n    try\n      MyInstance2.DoSomethingElse;\n\n      MyInstance3 := TMyClass3.Create;\n      try\n        MyInstance3.DoYetAnotherThing;\n      finally\n        FreeAndNil(MyInstance3);\n      end;\n    finally\n      FreeAndNil(MyInstance2);\n    end;\n  finally\n    FreeAndNil(MyInstance1);\n  end;\nend;<\/pre><\/div>\n\n\n\n<p>Probablemente sea m\u00e1s legible de la siguiente forma:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">procedure MyProcedure;\nvar\n  MyInstance1: TMyClass1;\n  MyInstance2: TMyClass2;\n  MyInstance3: TMyClass3;\nbegin\n  MyInstance1 := nil;\n  MyInstance2 := nil;\n  MyInstance3 := nil;\n  try\n    MyInstance1 := TMyClass1.Create;\n    MyInstance1.DoSomething;\n\n    MyInstance2 := TMyClass2.Create;\n    MyInstance2.DoSomethingElse;\n\n    MyInstance3 := TMyClass3.Create;\n    MyInstance3.DoYetAnotherThing;\n  finally\n    FreeAndNil(MyInstance3);\n    FreeAndNil(MyInstance2);\n    FreeAndNil(MyInstance1);\n  end;\nend;<\/pre><\/div>\n\n\n\n<p>Nota:<br>En este ejemplo simple, tambi\u00e9n podr\u00eda presentar un argumento v\u00e1lido de que el c\u00f3digo debe dividirse en 3 procedimientos separados, uno llam\u00e1ndose entre s\u00ed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C\u00f3mo se muestran las excepciones en varias bibliotecas<\/h2>\n\n\n\n<p> <p>En el caso de Lazarus LCL, las excepciones generadas durante los eventos (varias devoluciones de llamada asignadas a las propiedades OnXxx de los componentes LCL) se capturar\u00e1n y dar\u00e1n como resultado un agradable mensaje de di\u00e1logo que permite al usuario continuar y detener la aplicaci\u00f3n. Esto significa que sus propias excepciones no \u00absalen\u00bb de Application.ProcessMessages, por lo que no rompen autom\u00e1ticamente la aplicaci\u00f3n. Puede configurar lo que sucede usando TApplicationProperties.OnException.     De manera similar, en el caso de Castle Game Engine con CastleWindow: la excepci\u00f3n se captura internamente y da como resultado un buen mensaje de error. Por lo tanto, las excepciones no \u00absalen\u00bb de Application.ProcessMessages. Nuevamente, puede configurar lo que sucede usando Application.OnException. <\/p>Algunas otras bibliotecas GUI pueden hacer algo similar a lo anterior.   <p>En el caso de otras aplicaciones, puede configurar c\u00f3mo se muestra la excepci\u00f3n asignando una devoluci\u00f3n de llamada global a OnHaltProgram.<\/p><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-trasteando-por-vicio wp-block-embed-trasteando-por-vicio\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"TtSrjhXxNh\"><a href=\"https:\/\/jorgeturiel.es\/?p=320\">Introducci\u00f3n al lenguaje Pascal moderno para programadores (Parte 6)<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"\u00abIntroducci\u00f3n al lenguaje Pascal moderno para programadores (Parte 6)\u00bb \u2014 Trasteando por vicio\" src=\"https:\/\/jorgeturiel.es\/?p=320&#038;embed=true#?secret=89P6icjCAx#?secret=TtSrjhXxNh\" data-secret=\"TtSrjhXxNh\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Continuamos con la introducci\u00f3n al lenguaje Pascal Moderno. Esta entrada es una traducci\u00f3n al espa\u00f1ol, del texto original escrito por Michalis Kamburelis. Continuamos con la introducci\u00f3n al lenguaje Pascal Moderno. Esta entrada es una traducci\u00f3n al espa\u00f1ol, del texto original escrito por Michalis Kamburelis.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,25,26],"tags":[22,23,21,24],"class_list":["post-314","post","type-post","status-publish","format-standard","hentry","category-lazarus","category-pascal","category-programacion","tag-delphi","tag-lazarus","tag-pascal","tag-programacion"],"_links":{"self":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/314","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=314"}],"version-history":[{"count":8,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/314\/revisions"}],"predecessor-version":[{"id":493,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/314\/revisions\/493"}],"wp:attachment":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=314"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=314"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=314"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}