PDA

Ver la Versión Completa : como llamo a un procedimiento con parametros opcionales


luigi_cr
10-07-2007, 01:39:29
Ok este es el procedimiento que he creado los ultimos cuatro parametros son opcionales:

procedure X.opcionales(x1 : Integer; x2 : String;
x3 : String; x4 : String;
x5 : String; x6 : String;
x7 : String = '000000000000';
x8 : String = '00000000';
x9 : String = '000000';
x10 : String = '000000');

pero okupo llamar al procedimiento y pasarle solo los x1, x2, x3, x4, x5, x6 que son los obligados y ademas el parametro x9 por dar un ejemplo; yuo crei q simplemente dejaba el espacio en blanco cuando hacia la llamada al procedure:


opcionales(x1, x2, x3, x4, x5,
x6, , ,x9);

no paso ni x7, x8, x10, pero no me funciona me da el siguiente error:

[Error] X.pas(425): Expression expected but ',' found

la idea del procedure con parametros opcionales, es para llamarle varias veces con unicamente los parametrso que okupo pasarle.

dec
10-07-2007, 01:52:37
Hola,

Si no me equivoco no puedes hacer lo que quieres tal como quieres hacerlo. Se me ocurre que si no quieres ocupar un parámetro opcional, pero, necesitas indicar un parámetro opcional posterior... tal vez puedas establecer el parámetro que no necesitas con el valor por defecto. No sé si me explico.



procedure Proc(p1: string; p2: integer = 1; p3: integer = 2);
begin
{...}
end;

{...}

begin
Proc('cadena', 1, 3);
end;



Suponiendo que lo que me interesa realmente es que "llegue" el tercer parámetro, lo que puedo hacer es establecer el segundo parámetro con el valor por defecto. Creo que esa es la única manera de conseguir algo similar a lo que dices, pero, a lo mejor me equivoco. :)

eduarcol
10-07-2007, 01:55:32
La verdad la solucion expuesta por Dec es la mas facil y yo tampoco se si habra otra, pero de recomendacion es mas sencilo hacerlo asi que seguir esperando

luigi_cr
10-07-2007, 01:57:30
si entiendo tu respuesta y te agredesco, pero entonces que sentido tienen los parametros opcionales, si digamas kiera (en mi ejemplo) insertar, bueno los seis primeros q son obligatorios, y solamente el diez, de la forma que tu dices, entonces tendria que pasarle los diez parametros y asi no tiene mucho sentido el uso de parametros opcionales, gracias de todos modos.

dec
10-07-2007, 02:15:56
Hola,

Bueno. Estamos hablando de que es sintácticamente un error tratar de hacer lo que dices. Es decir, el compilador no toleraría esto:



Proc('cadena', , 3);



Y cualquier otra cosa pasa por un valor válido, sea este o no el determinado "por defecto" para el parámetro. Ya digo, no sé explicarme, pero, me parece algo de cajón que no funcione el asunto tal como quieres.

Ahora bien, contar con la posibilidad de establecer parámetros opcionales... podrá venir bien en algunas ocasiones, podrá no ser recomendable para otras... como suele ocurrir: no es el cuchillo el que mata.

Personalmente, encuentro la posibilidad de establecer parámetros opcionales una buena cosa. Puede ser útil no pocas veces, incluso con sus limitaciones, si quiere verse así. :)

Por cierto, en PHP, por ejemplo, el modo de tratar los parámetros opcionales es igual que en Delphi. E intuyo que no puede haber mucha diferencia con otros lenguajes.

luigi_cr
10-07-2007, 02:23:05
sip entendi tu respuesta y gracias, me parece un poco engorroso q en delphi se tenga que hacer asi, y si en JAVA o en VB cuando llamas al procedure y no quieres pasarle un parametro simplemente lo dejas en blanco, ya veo que en delphi no, gracias de todos modos

dec
10-07-2007, 02:24:44
Hola,

¿Cómo? ¿Que en Java o Visual Basic (+ Satán +) puede hacerse lo que dices? ¡Pero entonces estoy completamente equivocado! Ahora bien, ¿cómo es posible? ¿Podrías poner aquí algo de código y si no es mucha molestia explicarlo? No hay forma de "saltarse" un parámetro. Tal como lo dices y/o tal como yo lo entiendo no puede hacerse eso en ningún lenguaje de programación de que yo tenga una mínima noción...

Y estoy dispuesto a cortarme la... coleta. :D :D :D :D

eduarcol
10-07-2007, 02:36:14
Y estoy dispuesto a cortarme la... coleta.

jajaja esa estuvo bueno

Por intuicion creo que vb lo permite gracias a los tipos Variant, habria qe tratar de hacelo con la opcion explicit = true

dec
10-07-2007, 02:37:38
Hola,

Nada, nada... yo exigo pruebas. :)

eduarcol
10-07-2007, 02:40:53
Lamento no poder probarlo pero no tengo instalado VB y espero que comprendas qe no pretendo instalarlo :P

egostar
10-07-2007, 02:44:01
Yo creo que se refiere a esto


Pero args no es sólo un String. Es un arreglo de String. Eso es por el uso de [] en la declaración:

String args[]

Esos corchetes declaran que es un arreglo, en este caso, de String. Por qué la existencia de este parámetro en main? Esta clase ejecutará un programa de consola. Lo lanzaremos desde la línea de comando (el próximo punto a estudiar es cómo compilamos y ejecutamos la clase). Cuando escribimos un comando, podemos agregarle parámetros. Justamente esos parámetros opcionales son los que Java se encarga de entregarnos en el argumento args. Notemos que al declarar un arreglo, no hemos puesto la cantidad de elementos que tiene.


Aqui el link (http://www.ajlopez.net/ArticuloMuestra.php?Id=1).

Salud OS.

dec
10-07-2007, 03:32:13
Hola,

Bien puede ser egostar, pero, eso no deja de ser un parámetro. ¿Que puede incluir varias cadenas de caracteres? Sí; pero no deja de ser un solo parámetro. Ains... a ver si el amigo luigi_cr nos saca de dudas. :)

basti
10-07-2007, 09:36:20
Pues yo tampoco tengo instalado VB, y tampoco pienso instalarlo (a mi pc le diagnosticaron alergia al VB y se me puede resfriar). Pero te puedo confirmar que en VB se pueden saltar parámetros. Eso sí, al principio puede parecer muy bonito, pero cuando te encuentras código así (lo estoy escribiendo de memoria, así que puede haber algún error):


Sub Funcion(primero as Integer, Optional ByVal segundo As Integer = 8, Optional ByVal tercero As Integer = 3, Optional ByVal cuarto As Integer = 3, Optional ByVal quinto As Integer = 7, Optional ByVal sexto As Integer = 9, Optional ByVal septimo As Integer = 3) as integer
.
.
.
resultado = Funcion (3, , , variable1, 4, 5, 7)

' o

resultado = Funcion(3, cuarto = variable1, quinto = 4, sexto = 5, septimo = 7)

Neftali [Germán.Estévez]
10-07-2007, 10:07:50
Otra opción podría ser sobrecargar el método y crear dos llamadas diferentes con diferentes parámetros (si es que es muy común llamarla con ese parámetro relleno y el resto de los opcionesles no).


procedure X.opcionales(x1 : Integer; x2 : String;
x3 : String; x4 : String;
x5 : String; x6 : String;
x7 : String = '000000000000';
x8 : String = '00000000';
x9 : String = '000000';
x10 : String = '000000'); overload;

procedure X.opcionales(x1 : Integer; x2 : String;
x3 : String; x4 : String;
x5 : String; x6 : String;
x9 : String = '000000'
); overload;

La segunda llamada, llamaría a la primera rellenando el resto de parámetros opcionales. Sólo le veo utilidad en el caso que he comentado de que la llamada con el parámetro X9 rellenado y el resto de opcioneles vacíos sea muy habitual.

dec
10-07-2007, 10:46:29
Hola,


Pues yo tampoco tengo instalado VB, y tampoco pienso instalarlo (a mi pc le diagnosticaron alergia al VB y se me puede resfriar). Pero te puedo confirmar que en VB se pueden saltar parámetros.


Qué interesante... de verdad que es un motivo más para NO usar eso. :)

Es broma. Pero, vamos... si esto no queda como el culo del profesor Cojonciano (http://es.wikipedia.org/wiki/El_profesor_Cojonciano) que venga dios y lo vea:


resultado = Funcion (3, , , variable1, 4, 5, 7)


Mondieu... :D :D

Al González
10-07-2007, 17:00:13
¡Hola a todos!

Luigi_cr:

Conozco, he utilizado, pero no me agrada del todo esa flexibilidad adicional de Visual Basic para el manejo de los parámetros opcionales porque propicia el viejo vicio de la parametrización excesiva, en lugar de fomentar una adecuada programación orientada a objetos. Vaya, este tipo de cosas son el quid de las eternas rivalidades entre Delphi y Visual Basic, entre lo bien pensado y lo que vende al vulgo.

Dices que no tiene mucho sentido que Delphi impida omitir parámetros intermedios. Bien, eso sería cierto si por otra parte tuviera sentido un método con 10 parámetros y no existiera en Delphi la sobrecarga de funciones (esta característica se incluyó en Delphi al mismo tiempo que los parámetros opcionales).

Si lo analizas de una manera objetiva, te darás cuenta que rara vez es menester crear un método con más de tres o cuatro parámetros. La POO está hecha para simplificar la manera de trabajar con los datos y la funcionalidad que hay alrededor de ellos. Un método como ese X.Opcionales tendría que ser revisado.

Ahora bien, ya que tengas un método más decente, digamos, que sólo declare unos tres o cuatro parámetros, podrías recurrir a la sobrecarga (directiva Overload), como bien lo sugirió Neftali, para entonces sí permitir la "omisión" de un parámetro intermedio, que en realidad sería utilizar la versión del método que no requiere (que asume) tal parámetro.


TMiSQLConnection = Class (TSQLConnection)
Public
{ Regresar al punto de restauración de nombre Name }
Procedure RollbackSavePoint (Const Name :String;
Const Release :Boolean = False); Overload;

{ Regresar al último punto de restauración marcado }
Procedure RollbackSavePoint (Const Release :Boolean = False);
Overload;


Espero esto sea de utilidad.

Un abrazo opcional.

Al González. :)

luigi_cr
10-07-2007, 17:49:48
la idea no era comparar si vb o delphi es mejor, yo me quedo con JAVA, pero bueno para que voy a sobrecargar un metodo diez veces si la funcion q cumple es la misma, es decir voy a digitar diez veces el mismo codigo noo, para eso son los parametros opcionales, el procedimiento siempre va hacer lo mimo lo unico que va cambiar es el resultado.

egostar
10-07-2007, 18:31:53
la idea no era comparar si vb o delphi es mejor, yo me quedo con JAVA, pero bueno para que voy a sobrecargar un metodo diez veces si la funcion q cumple es la misma, es decir voy a digitar diez veces el mismo codigo noo, para eso son los parametros opcionales, el procedimiento siempre va hacer lo mimo lo unico que va cambiar es el resultado.

Bueno, todo surgió a raíz de tu comentario sobre lo que puedes hacer con VB o java y que Delphi NO puedes hacer.

Además, te han dado respuestas de porque no lo hace Delphi, si es mejor o peor no es el caso, mas bien el porque Delphi no lo maneja así.

Salud OS.

gabrielkc
10-07-2007, 19:06:48
En delphi se puede hacer una llamada a un procedimiento evitando algún parámetro cuando se usa OLE:


Mar:=CreateOleObject('Excel.Application');
Mar.WorkBooks.Open(ExtractFilePath(Application.ExeName)+'\Producto_Terminado_bco.xls');
Mar.Sheets[1].Copy(,Mar.Sheets[1]);


El código anterior copia la primera hoja de el documento después de la hoja 1, la declaración del procedimiento es el siguiente:


procedure Copy(Before, After: OleVariant; lcid: Integer); safecall;

Al González
10-07-2007, 19:08:18
¡Hola de nuevo!

...para que voy a sobrecargar un metodo diez veces...
¿Alguien te sugirió que hicieras tal cosa? :eek: De hecho, si ese fuese el derrotero, no serían 10 sobrecargas sino casi mil. :rolleyes:

Insisto que un método con 10 parámetros es algo que despierta muchas dudas respecto a una buena estructuración de clases. ¿Por qué no nos das un poco de contexto para ampliar el panorama y afinar propuestas?

Te invito a leer de nuevo mi comentario anterior.

Un abrazo incomparable.

Al González. :)

Delphius
10-07-2007, 20:22:36
Hola,

Opino igual que Al, ¿10 parámetros? ¿Que de ellos el 40% sea opcional?
Desde ya decanto esa opción. Creo que deberías reconsiderar un mejor análisis de la situación.
Yo he llegado a declarar funciones, y clases... pero ninguna excede cuanto mucho a los 4 o 5 parámetros.

¿No podrías considerar que agunos parámetros sean propiedades de la clase?

Con respecto a la opción que te recomienda Neftali, creo que es la acertada. Y eso no quiere decir que debas codificar 10 veces el mismo código. Como te lo han dicho hay un error de diseño. La solución es buscar la mínima expresión común e implementarla en una función. Cada sobre carga llamará a dicha función (que debe ser privada, según una primera impresión y análisis).

El objetivo de los parámetros opcionales es evitar estar declarando valores que en la mayoría de los casos son considerados por defecto (o considerado lo mayormente esperado), por lo cual indicar un valor distinto sería considerado un caso "particular" (algo no habitual).

Este enfoque puede llevarse a la inversa. Es decir que nadie puede impedirte que emplees el valor opcional (por defecto) para evitar hacer una cosa. Algo como esto:


const
CONST_NO_HAGAS_ESTO = 4;

//....

X.procedure EjemploALaInversa(A: integer; B: real; C: integer = CONST_NO_HAGAS_ESTO);
// posiblemente deba llevar la clausura overload....
begin
// ...
if C <> CONST_NO_HAGAS_ESTO
then begin
// Lo que quieres que haga...
end
else begin
// Lo que no quieres que haga...
end;
//...
end;


En resumen lo que he tratado de decirte es que podrías llevar y emplear el valor opcional en la forma inversa, es decir que si se suministra un valor distinto que se haga la operación que deba realizar.

Para finalizar, debo decirte que a pesar de que esta alternativa pueda llegar a funcionar sigue siendo un error conceptual y de diseño ya que el modo de trabajo no es el normal o "el esperado" del lenguaje. Puede llevar a confusiones en el futuro, y lo hace muy dificil de seguirle un correcto mantenimiento y documentación.

Espero que se me entienda.
Saludos,

Neftali [Germán.Estévez]
11-07-2007, 11:09:00
...pero bueno para que voy a sobrecargar un metodo diez veces si la funcion q cumple es la misma

Creo que nadie ha dicho tal cosa... Yo al menos no.
Contando que el método esté bien definido y sin poner en duda la definición de la cabecera (cosa que empiezo a dudar dados los problemas que te surgen), lo que yo he comentado es:


Sólo le veo utilidad en el caso que he comentado de que la llamada con el parámetro X9 rellenado y el resto de opcioneles vacíos sea muy habitual.


¡¡Mira que está subrayado!! Está claro que sólo tiene utilidad en ese caso. Que de las 100 llamadas al método que haces la mayoría sean de una forma o de otra (por decir algo). Si llamas indistintamente de 10 forma distintas, nadie ha dicho que tengas que sobrecargar 10 veces.

En ese caso, seguramente habría que cambiar la cabecera de la función y llamar con dos arrays de parámetros, por ejemplo:
(x1:Integer; xNames:array of String; xValues: array of string)

Un array fijo de 4 posiciones, sólo para los opcionales o algun otro sistema que se ajuste a tus necesidades concretas (9 parámetros de tipo string, 4 opcionesles y que además llamas de la forma comentada).

luigi_cr
14-07-2007, 20:59:24
Muchas Gracias a todos los que, tomarón un poco de sutiempo y postearón tratando de ayudar, al final de cuentas deje el procedimiento como estaba, me parecieron execelentes la mayoria de respuestas...Gracias

Creo que con esto se cierra el tema....

Gracias de nuevo.