Recent

Author Topic: aprendizaje y preguntas sobre freepascal  (Read 5361 times)

zelda16bit

  • Full Member
  • ***
  • Posts: 118
aprendizaje y preguntas sobre freepascal
« on: June 05, 2021, 11:57:40 am »
Bueno...

Pues despues de un tiempo probando cosas vuelvo definitivamente con pascal y ya no me muevo.Como he estado un tiempo parado con pascal he decidido volver a empezar de nuevo y para eso he encontrado una documentacion que es la mas completa que he encontrado.

La he traducido con el traductor y mas o menos me sirve,voy a poner por aqui un enlace para ver que os parece...una vez termine con esta documentacion me pondre con allegro 5,pero necesito vuestra ayuda porque solo como que no avanza y me quedo atascado.
https://castle-engine.io/modern_pascal_introduction.html

De momento tengo algunas preguntas

¿Esto para que es? {$mode objfpc}{$H+}{$J-}

He visto en la documentacion que para devolver un valor en una funcion utiliza 'result' pero yo aprendi que se usaba el mismo nombre de la funcion,¿cual es la forma correcta?

Me he quedado en la parte de los enumerados pero no me queda muy claro,estoy usando esto {$scopedenums on} para facilitar el uso del enumerado,no entiendo muy bien como usar esto.

Code: Pascal  [Select][+][-]
  1. type
  2.   TAnimalKind = (akDuck, akCat, akDog);
  3.   TAnimals = set of TAnimalKind;
  4.   TAnimalKind = (akDuck, akCat, akDog);
  5.   TAnimalNames = array [TAnimalKind] of string;
  6.  
« Last Edit: June 05, 2021, 10:06:36 pm by zelda16bit »

440bx

  • Hero Member
  • *****
  • Posts: 3921
Re: aprendizaje y preguntas sobre freepascal
« Reply #1 on: June 05, 2021, 03:35:51 pm »
¿Esto para que es? {$mode objfpc}{$H+}{$J-}
El compilador FPC tiene una serie de modos, el modo objfpc es uno de ellos y es probablemente el mas usado debido a que provee caracteristicas que son muy communes, por ejemplo "class".  {$h+} selectiona "LONGSTRINGS ON" en ese modo, un string es un apuntador a un bloque de memoria manejado por el compilador que almacena los caracteres que forman el string.  {$J-} le indica al compilador que no debe acceptar "constantes" que puedan ser escritas/modificadas.

He visto en la documentacion que para devolver un valor en una funcion utiliza 'result' pero yo aprendi que se usaba el mismo nombre de la funcion,¿cual es la forma correcta?
Las dos formas son correctas pero usar "result" es mas flexible porque si decides cambiar el nombre de la function, no tienes que cambiar cada linea donde la function is asignada un valor.


Me he quedado en la parte de los enumerados pero no me queda muy claro,estoy usando esto {$scopedenums on} para facilitar el uso del enumerado,no entiendo muy bien como usar esto.
Una enumeracion is simplemente un grupo de constantes.  El nombre del group es el nombre de la enumeracion.

{$scopedenums on} cambia la forma de referirse a una constante.  si esta "on", las constantes tienen que ser referidas con el nombre de la enumeracion (que identifica el grupo que contiene la constante.) 

Es muy util, porque permite tener constantes con el mismo nombre.  si scopedenums esta "off" no es possible usar un nombre para mas de una constante, el compilador se queja que hay un duplicado.  si scopedenums esta "on" el compilador puede aceptar constantes con el mismo nombre siempre y cuando esten en differentes grupos/enumeraciones porque el nombre completo de la constante es <nombre de la enumeracion>.<nombre de la constante>.

Code: Pascal  [Select][+][-]
  1. type
  2.   TAnimalKind = (akDuck, akCat, akDog);
  3.   TAnimals = set of TAnimalKind;
  4.   TAnimalKind = (akDuck, akCat, akDog);
  5.   TAnimalNames = array [TAnimalKind] of string;
  6.  
El compilador se va a quejar que TAnimalKind no es un nombre unico.  Las definiciones que tienes alli tienen los significados siquientes:

TAnimalKind es un grupo de constantes.  La constante akDuck es zero (en enumeraciones, el compilador empieza a asignar valores a partir de zero), akCat es 1 y akDog es 2.

TAnimals es un conjunto de TAnimalKind.  Cuando akDog es anadido en un conjunto de TAnimals (una variable de tipo "TAnimals"), un bit que identifica que akDog es un miembro del conjunto es asignado el valor "1", si akDog es retirado del conjunto entonces ese bit es asignado zero.  Un set es un grupo de bits que indica si un miembro esta or no esta en el conjunto.

TAnimalNames es un arreglo de "string".  El arreglo esta "ordenado" por las constantes nombradas en TAnimalKind.  Es decir, TAnimalNames[akDuck] identifica un string que contiene el nombre en caracteres que corresponde a akDuck (muy probablemente un string "Duck"), lo mismo para akCat, akDog.

lo que sigue es un programa muy corto que usa las definiciones que mostrates:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2.  
  3. program DataTypes;
  4.  
  5. type
  6.   TAnimalKind  = (akDuck, akCat, akDog);
  7.   TAnimals     = set of TAnimalKind;
  8.   TAnimalNames = array [TAnimalKind] of string;
  9.  
  10. var
  11.   AnimalKind   : TAnimalKind;
  12.  
  13.   Animals      : TAnimals     = [];                   { vacio/empty           }
  14.  
  15.   AnimalNames  : TAnimalNames = ('Duck', 'Cat', 'Dog');
  16.  
  17. begin
  18.   writeln;
  19.  
  20.   AnimalKind := akCat;
  21.  
  22.   Animals    := [akDuck];
  23.  
  24.   writeln(' akDog  esta en el conjunto de animales ? ', akDog  in Animals);
  25.   writeln(' akDuck esta en el conjunto de animales ? ', akDuck in Animals);
  26.  
  27.   AnimalKind := akDog;
  28.  
  29.   writeln;
  30.   writeln(' un akDog se llama un                   : ', AnimalNames[AnimalKind]);
  31.  
  32.  
  33.  
  34.   writeln;
  35.   writeln('press ENTER/RETURN to end this program');
  36.   readln;
  37. end.
  38.  
  39.  
  40.  
HTH.
« Last Edit: June 05, 2021, 03:41:04 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: aprendizaje y preguntas sobre freepascal
« Reply #2 on: June 05, 2021, 07:52:35 pm »
Para devolver valores también puede usarse la meta-función Exit.  La diferencia está en que usar Result o el nombre de la función no termina la función, mientras que llamando Exit sí.  Por ejemplo:

Code: Pascal  [Select][+][-]
  1. program Ejemplo;
  2.  
  3.   function UnValorCualquiera: String;
  4.   begin
  5.   { Ponemos un valor en Result. }
  6.     Result := 'Valor 1';
  7.   { Sale de la función devolviendo un valor. }
  8.     Exit ('Valor 2');
  9.   { Esto nunca se ejecutará. }
  10.     Result := 'Valor 3'
  11.   end;
  12.  
  13. begin
  14.   WriteLn (UnValorCualquiera);
  15.   ReadLn
  16. end.
  17.  

Esto es bastante útil en funciones complejas, ya que también puedes usar el contenido de Result en operaciones.

Code: Pascal  [Select][+][-]
  1.   function Factorial (aNumero: LongInt): LongInt;
  2.   begin
  3.     if aNumero <= 2 then Exit (aNumero);
  4.     Result := aNumero;
  5.     repeat
  6.       Dec (aNumero);
  7.       Result := Result * aNumero
  8.     until aNumero < 3
  9.   end;
  10.  
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Re: aprendizaje y preguntas sobre freepascal
« Reply #3 on: June 05, 2021, 10:02:56 pm »
Gracias por la ayuda. ;)

Tengo mas preguntas.

Esto para que sirve y como se usa,porque en el manual no lo explica muy bien.
Code: Pascal  [Select][+][-]
  1. property MyIntProperty: Integer read MyInt write
  2.  

Y esto de virtual y override no llego a entender muy bien para que sirve.
Code: Pascal  [Select][+][-]
  1.   TMyClass = class
  2.     MyInt: Integer;
  3.     procedure MyVirtualMethod; virtual;
  4.   end;
  5.  
  6.   TMyClassDescendant = class(TMyClass)
  7.     procedure MyVirtualMethod; override;
  8.   end;
  9.  

Edson

  • Hero Member
  • *****
  • Posts: 1296
Re: aprendizaje y preguntas sobre freepascal
« Reply #4 on: June 08, 2021, 06:34:24 pm »
Esto para que sirve y como se usa,porque en el manual no lo explica muy bien.
Code: Pascal  [Select][+][-]
  1. property MyIntProperty: Integer read MyInt write
  2.  


Eso define una propiedad. Aunque le falta completar el "write ...". La sintaxis correcta la puedes encontrar en la documentación.

Recordando cuando dictaba clases de POO:

Una propiedad permite crear una barrera entre una variable miembro de un objeto y el exterior. Constituye la base de lo que se conoce como "encapsulamiento".

El uso de propiedades permite:
1. Crear atributos de solo lectura, lectura/escritura/lectura-escritura.
2. Restringe el acceso a ciertas variables de estado de un objeto o unidad. Relacionado a 1.
3. Permite crear rutinas de validación previa antes de asignar valores a los atributos de un objeto. Esto es útil para validaciones de rango.
4. Permite controlar, seguir y depurar mejor los cambios en los atributos. Por ejemplo, si quiero ver cuando se cambia el valor de un atributo, se puede incluir un simple punto de ruptura en el depurardor.
5. Permite ocultar la implementación de estados, porque una propiedad puede hacer pensar que hay solo una simple variable detrás, pero en la práctica puede haber un algoritmo completo de lectura/escritura que utiliza diversos atributos y condicionales.
6. Permite realizar cambios en la implementación de un objeto, manteniendo la interfaz de propiedades sin cambios. Esto es útil cuando se trabaja por capas y se quiere refactorizar o modificar alguna capa, sin afectar a las demás.

Las propiedades son una característica muy útil si se sabe usar, pero también puede ser problemática. Lenguajes como Java o C++, carecen de esta característica y solamente implementan el encapsulamiento mediante el uso de "getters" y "setters".

Los "getters" y "setters" también se pueden usar en Free Pascal (de hecho también en Pascal) porque finalmente son solo procedimientos y funciones, pero son útiles para realizar un mejor seguimiento y control de las lecturas y escrituras hacia un atributo.

Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Re: aprendizaje y preguntas sobre freepascal
« Reply #5 on: June 08, 2021, 09:56:24 pm »
Gracias por la explicacion Edson,he practicado un poco con esto pero el codigo queda muy lioso y creo que no lo voy a usar,usare lo que comentas de getters y setters.

Pues ya he terminado de leer el manual,ahora voy a preguntar sobre algunas cosas que no me han quedado claras,pero lo que voy a hacer es crear un tema por cada pregunta. :)

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: aprendizaje y preguntas sobre freepascal
« Reply #6 on: June 09, 2021, 12:12:53 am »
Gracias por la explicacion Edson,he practicado un poco con esto pero el codigo queda muy lioso y creo que no lo voy a usar,usare lo que comentas de getters y setters.

No es tan complicado. Supón que tienes esto:
Code: Pascal  [Select][+][-]
  1. type
  2.   TMiClase = class
  3.   private
  4.     FUnEntero: Integer;
  5.   public
  6.     property UnEntero: Integer read FUnEntero write FUntero;
  7.   end;
lo que hace que leyendo o escribiendo en UnEntero acceda directamente al campo FUnEntero .
Ahora supón que más tarde necsites que además la clase haga algo con ese valor, aparte de almacenarlo (piensa, por ejemplo, en las propiedades Width o Heigth de un control): como usaste una propiedad puedes cambiar la implementación a:
Code: Pascal  [Select][+][-]
  1. type
  2.   TMiClase = class
  3.   private
  4.     FUnEntero: Integer;
  5.     procedure SetUnEntero(AValue: Integer);
  6.   public
  7.     property UnEntero: Integer read FUnEntero write SetUnEntero;
  8.   end;

Como ves, al leer la propiedad sigues accediendo directamente al campo, pero al escribirla se hace a través de un procedimiento en el que podrías hacer lo que necesites aparte de almacenar el valor en FUnEntero:
Code: Pascal  [Select][+][-]
  1. procedure TMiClase.SetUnEntero(AValue: Integer);
  2. begin
  3.   if FUnEntero <> AValue then begin
  4.     FUnEntero := AValue;
  5.     { y cualquier otra cosa que quieras hacer con el valor }
  6.   end;
  7. end;

Si, por ejemplo, representase el tamaño de un "array", podrías añadir: SetLenght(FTheArray, AValue); o cualquier otra cosa que quieras hacer. La cuestión es que no tendrías que cambiar nada más en tu programa (al menos en teoría), porque la implementación de la propiedad es un asunto interno, "privado" dde la clase y nada más.

Y lo mismo vale para el "getter", si (por ejemplo) necesitases llamar a alguna funcion del SO o algo así para leer el valor.

Y eso es todo, básicamente: se trata de que la clase presente una faceta única de cara al exterior, no importa lo que esté haciendo (o los efectos secundarios esperados) para "leer" o "escribir" el valor.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Re: aprendizaje y preguntas sobre freepascal
« Reply #7 on: June 09, 2021, 04:09:39 pm »
Gracias por la detallada explicacion Lucamar,tendre que practicar mas hasta cogerle el tranquillo. :)

 

TinyPortal © 2005-2018