lunes, 20 de mayo de 2013

Procedimientos y Clases Visual FoxPro


Procedimientos y funciones definidas por el usuario

Los procedimientos y funciones permiten mantener en un único lugar el código que utiliza con frecuencia y llamarlo a través de su aplicación siempre que lo necesite. Esto hace que su código sea más fácil de leer y mantener, ya que en un procedimiento el cambio se realiza una sola vez, no varias veces como ocurre en un programa.
En Visual FoxPro, los procedimientos son similares a éste:
PROCEDURE myproc
  * This is a comment, but it could be executable code
ENDPROC
Tradicionalmente, los procedimientos contienen código que usted escribe para realizar una operación y funciones que calculan y devuelven un valor. En Visual FoxPro, las funciones son similares a los procedimientos:
FUNCTION myfunc
  * This is a comment, but it could be executable code
ENDFUNC
Puede incluir procedimientos y funciones en un archivo de programa distinto o al final de un archivo de programa que contenga código normal de programa. En un archivo de programa no puede tener código ejecutable de programa a continuación de los procedimientos y las funciones.
Si incluye sus procedimientos y funciones en un archivo de programa distinto, podrá hacer accesibles estos procedimientos y funciones desde su programa si utiliza el comando SET PROCEDURE TO. Por ejemplo, para un archivo llamado FUNPROC.PRG, utilice el siguiente comando en la ventana Comandos:
SET PROCEDURE TO funproc.prg

Llamar a un procedimiento o a una función

Hay dos formas de llamar a un procedimiento o a una función en sus programas:
  • Utilizar el comando DO. Por ejemplo:
    DO myproc
    
    –O bien–
  • Incluir detrás del nombre de la función un par de paréntesis. Por ejemplo:
    myfunc( )
    
Cada uno de estos métodos puede ampliarse enviando o recibiendo valores desde el procedimiento o la función.

Enviar valores a un procedimiento o a una función

Para enviar valores a procedimientos o funciones se incluyen parámetros. Por ejemplo, el procedimiento siguiente acepta un solo parámetro:
PROCEDURE myproc( cString )
   * The following line displays a message
   MESSAGEBOX ("myproc" + cString)
ENDPROC
Nota   Incluir los parámetros entre paréntesis en la línea de definición de un procedimiento o una función, por ejemplo PROCEDURE myproc(cString), indica que el parámetro tiene alcance local al procedimiento o la función. También puede permitir que una función o un procedimiento acepte parámetros de alcance local mediante LPARAMETERS.
Los parámetros funcionan de manera idéntica en una función. Para enviar un valor como un parámetro a este procedimiento o a una función, podría utilizar una cadena o una variable que contuviera una cadena, como se muestra en la tabla siguiente.
Transferencia de parámetros
CódigoComentarios
DO myproc WITH cTestString
DO myproc WITH "test string"
Llama a un procedimiento y transfiere una variable de caracteres o una cadena literal.
myfunc("test string")
myfunc( cTestString )
Llama a una función y transfiere una copia de una cadena literal o una variable de caracteres.
Nota   Si llama a un procedimiento o función sin usar el comando DO, la configuración de UDFPARMScontrola cómo se transfieren los parámetros. De forma predeterminada, UDFPARMS se establece como VALUE, por lo que se transferirán copias de los parámetros. Cuando utilice DO, se empleará el parámetro real (el parámetro se transfiere por referencia) y cualquier cambio realizado en el procedimiento o en la función se reflejará en los datos originales, cualquiera que sea la configuración de UDFPARMS.
Puede enviar múltiples valores a un procedimiento o función si los separa mediante comas. Por ejemplo, el siguiente procedimiento espera tres parámetros: una fecha, una cadena de caracteres y un número.
PROCEDURE myproc( dDate, cString, nTimesToPrint )
   FOR nCnt = 1 to nTimesToPrint
      ? DTOC(dDate) + " " + cString + " " + STR(nCnt)
   ENDFOR
ENDPROC
Podría llamar a este procedimiento mediante la siguiente línea de código:
DO myproc WITH DATE(), "Hello World", 10

Recibir valores desde una función

El valor devuelto de forma predeterminada es verdadero (.T.), pero puede utilizar el comando RETURN para devolver cualquier valor. Por ejemplo, la siguiente función devuelve una fecha correspondiente a dos semanas después de la fecha que se ha pasado como parámetro.
FUNCTION plus2weeks
PARAMETERS dDate
   RETURN dDate + 14
ENDFUNC
La siguiente línea de código almacena el valor devuelto desde esta función en una variable:
dDeadLine = plus2weeks(DATE())
En la tabla siguiente se muestran las formas en que puede almacenar o mostrar valores devueltos por una función.
Manipular valores devueltos
CódigoComentarios
var = myfunc( )
Almacena en una variable el valor devuelto por la función.
? myfunc( )
Imprime en la ventana de resultado activa el valor devuelto por la función.

Comprobar parámetros en un procedimiento o en una función

Es conveniente comprobar que los parámetros enviados a su procedimiento o a su función son los que espera recibir. Puede utilizar las funciones TYPE() y PARAMETERS() para comprobar el tipo y el número de parámetros enviados a su procedimiento o a su función.
El ejemplo de la sección anterior necesita recibir un parámetro de tipo Date. Puede utilizar la función TYPE( ) para asegurarse de que el valor que su función recibe es del tipo adecuado.
FUNCTION plus2weeks( dDate )
   IF TYPE("dDate") = "D"
      RETURN dDate + 14
   ELSE
      MESSAGEBOX( "You must pass a date!" )
      RETURN { - - }      && Return an empty date
   ENDIF
ENDFUNC
Si un procedimiento espera menos parámetros de los que recibe, Visual FoxPro generará un mensaje de error. Por ejemplo, si especificó dos parámetros pero llamó al procedimiento con tres parámetros, obtendrá un mensaje de error. Pero si un procedimiento espera más parámetros de los que recibe, los parámetros adicionales simplemente se inicializarán como falso (.F.). Puesto que no hay ninguna forma de decir si el último parámetro se estableció como falso (.F.) o se omitió, el siguiente procedimiento comprueba que se ha enviado el número correcto de parámetros:
PROCEDURE SaveValue( cStoreTo, cNewVal, lIsInTable )
   IF PARAMETERS( ) < 3
      MESSAGEBOX( "Too few parameters passed." )
      RETURN .F.
   ENDIF
   IF lIsInTable
      REPLACE (cStoreTo) WITH (cNewVal)
   ELSE
      &cStoreTo = cNewVal
   ENDIF
   RETURN .T.
ENDPROC

Clases de Visual FoxPro

Todas las propiedades, eventos y métodos de un objeto se especifican en la definición de clase. Además, las clases tienen las siguientes características que las hacen especialmente útiles para crear código reutilizable y fácil de mantener:
  • Encapsulamiento
  • Subclases
  • Herencia

Ocultar la complejidad innecesaria

Cuando instale un teléfono en la oficina, lo más probable es que no le interese el funcionamiento interno del aparato para la recepción de llamadas, la realización o la finalización de conexiones con centralitas electrónicas o la conversión de las pulsaciones de tecla en señales electrónicas. Lo único que necesitará saber es que puede levantar el auricular, marcar los números apropiados y hablar con la persona con la que desea hablar. La complejidad de realizar esa conexión queda oculta. La ventaja de ignorar los detalles internos de un objeto para poder centrarse en los aspectos del objeto que necesita utilizar se denomina abstracción.
El encapsulamiento, que empaqueta el código de métodos y propiedades en un mismo objeto, contribuye a la abstracción. Por ejemplo, las propiedades que determinan los elementos de un cuadro de lista y el código que se ejecuta al elegir un elemento de la lista pueden encapsularse en un único control que se agrega a un formulario.

Aprovechar la eficacia de las clases existentes

Una subclase puede tener toda la funcionalidad de una clase existente, además de la funcionalidad y los controles adicionales que quiera darle. Si la clase es un teléfono básico, podrá tener subclases que tengan toda la funcionalidad del teléfono original y todas las características especializadas que desee darles.
La creación de subclases es un modo de reducir la cantidad de código que hay que escribir. Puede comenzar definiendo un objeto que sea similar al deseado y personalizarlo.

Simplificar el mantenimiento de código

Con la herencia, si realiza un cambio en una clase, ese cambio se reflejará en todas las subclases que se basen en ella. Esta actualización automática ahorra tiempo y trabajo. Por ejemplo, si un fabricante de teléfonos quisiera cambiar los teléfonos de dial por teléfonos de botones, se ahorraría mucho trabajo si pudiera hacer el cambio en el diagrama original y hacer que todos los teléfonos fabricados anteriormente con ese diagrama heredaran automáticamente la nueva característica, en lugar de tener que agregarla a todos los teléfonos existentes individualmente.
La herencia no funciona con el hardware, pero sí en el software. Si descubre un error en una clase, en lugar de tener que cambiar el código de todas las subclases podrá corregirlo una única vez en la clase y el cambio se propagará a todas las subclases pertenecientes a ella.

Contenedores y no contenedores

Los dos tipos principales de clases de Visual FoxPro y por extensión, de objetos de Visual FoxPro, son las clases de contenedor y las clases de control.

Clases de contenedor

Los contenedores pueden incluir otros objetos y permiten el acceso a los objetos que contienen. Por ejemplo, si crea una clase de contenedor que consta de dos cuadros de lista y dos botones de comando y, a continuación, agrega a un formulario un objeto basado en esta clase, cada objeto individual podrá manipularse en tiempo de ejecución y en tiempo de diseño. Puede cambiar fácilmente las posiciones de los cuadros de lista o los títulos de los botones de comando. También puede agregar objetos al control en tiempo de diseño; por ejemplo, puede agregar etiquetas para identificar los cuadros de lista.
La tabla siguiente muestra los posibles componentes de cada clase de contenedor:
ContenedorPuede contener
Grupos de botones de comandoBotones de comando
ContenedorCualquier control
ControlCualquier control
CustomCualquier control, marco de página, contenedor, personalizado
Conjuntos de formulariosFormularios, barras de herramientas
FormulariosMarcos de página, cualquier control, contenedores, personalizado
Columnas de cuadrículaEncabezados y cualquier objeto excepto conjuntos de formularios, formularios, barras de herramientas, cronómetros y otras columnas
CuadrículasColumnas de cuadrícula
Grupos de botones de opciónBotones de opción
Marcos de páginaPáginas
PáginasCualquier control, contenedores, personalizado
ProyectoArchivos, servidores
Barras de herramientasCualquier control, marcos de página, contenedor

Clases de control

Las clases de control están más encapsuladas que las clases de contenedor, pero por esa misma razón es posible que sean menos flexibles. Las clases de control no tienen un metodo addobject.

No hay comentarios:

Publicar un comentario