Foro de elhacker.net

Programación => Programación Visual Basic => Mensaje iniciado por: Psyke1 en 2 Octubre 2011, 01:08 am



Título: vb6 es tonto
Publicado por: Psyke1 en 2 Octubre 2011, 01:08 am
Hola chicos, bueno a raíz de una discusión con la profesora de programación he investigado sobre los Ifs de vb6... :rolleyes:

En esta situación:
Código
  1. If A = True Or B = False Then
Lo lógico sería que al leer A=True no comprobara Lo siguiente puesto que la condición se cumpliría de todas formas. :)
Pero no, vb te comprueba TODO el If pase lo que pase en todos los casos. :¬¬

Aquí un código que lo demuestra:

Código
  1. Option Explicit
  2.  
  3. Private Function OrTest(ByVal bReturn As Boolean) As Boolean
  4.    '// Imprimo un texto para saber que he pasado por la función.
  5.    Debug.Print Time$, "Función con el argumento " & bReturn & " llamada."
  6.    OrTest = bReturn
  7. End Function
  8.  
  9. Private Sub Form_Load()
  10.  
  11.    '// Aquí lo logico sería comprobar las dos ya que
  12.    '// si la primera no es true, lo puede ser la segunda.
  13.    If OrTest(False) Or OrTest(False) Then
  14.        '// Nothing
  15.    End If
  16.  
  17.    Debug.Print String$(75, "=")
  18.  
  19.    '// Lo lógico sería que se saltase la segunda función puesto
  20.    '// que la primera es true, pero no, nuestro querido vb
  21.    '// comprueba igual...
  22.    If OrTest(True) Or OrTest(False) Then
  23.        '// Nothing
  24.    End If
  25. End Sub
  26.  

Retorno:
Código:
00:27:48      Función con el argumento Falso llamada.
00:27:48      Función con el argumento Falso llamada.
===========================================================================
00:27:48      Función con el argumento Verdadero llamada.
00:27:48      Función con el argumento Falso llamada.


Sé que alguno dirá: ¿y a mí qué más me da si el resultado es el mismo?
Bueno, pues imagina que tienes un If tal que así:

Código
  1. If Calculo(1) Or Calculo(2) Or Calculo(3) Or Calculo(4) Or Calculo(5) Then
  2.    '...
  3. End If
La función Calculo() es un algoritmo complejo y tarda 1 segundo de media.
Si fuera otro lenguaje de programación si Calculo(1) es true se saltaría los demás, pero nuestro querido vb6 llamará a todas las demás funciones perdiendo tiempo innecesariamente... :-\ Pasando de 1 seg a 5 en este caso.
La alternativa que propongo en estos casos es (no son agradables a la vista, aviso :xD) :

Sustituir esto:
Código
  1.    If A(324) = 45 Or B(12) = 2 Or B(4563) = 56 Then
  2.        Call DoIt
  3.    End If

Por esto:
Código
  1.    If A(324) = 45 Then
  2.        Call DoIt
  3.    ElseIf B(12)=2 Then
  4.        Call DoIt
  5.    ElseIf B(4563) = 56 Then
  6.       Call DoIt
  7.    End If

Esto:
Código
  1.    If A(324) = 45 And B(12) = 2 And B(4563) = 56 Then
  2.        '...
  3.    End If

Por esto:
Código
  1.    If A(324) = 45 Then
  2.        If B(12) = 2 Then
  3.            If B(4563) = 56 Then
  4.                '...
  5.            End If
  6.        End If
  7.   End If
Con esto no quiero decir que lo hagáis así de normal, sólo cuando necesitemos velocidad.
Hice estas pruebas a ver si algún lenguaje más era tonto, pero por ahora sólo es vb6.
Si alguien sabe de otro hacedmelo saber, me interesa mucho.
Dedico este articulo a Karcrack, BlackZero, TheSwash y raul338 por orientarme y ayudarme con los test.

VB.NET tiene una expresion para evitar esto:
Código:
Short-Circuiting Logical Operations http://msdn.microsoft.com/en-us/library/wz3k228a.aspx

Más info:
Código:
http://en.wikipedia.org/wiki/Short-circuit_evaluation

Espero que al menos a alguien le sirva todo esto. :)

DoEvents! :P


Título: Re: vb6 es tonto
Publicado por: $Edu$ en 2 Octubre 2011, 01:18 am
No sabias esto de antes? :S hasta yo lo sabia xD

En .net por ejemplo ya tienes opcion, si quieres un "Or" comun como en vb6 o un "Or" mas "rapido" que saldra si ya no cambiara en nada las siguientes condiciones con el final.

Te da para elegir porque a veces aunque la condicion final no cambiara, necesitamos que entre a una funcion que mostrara talvez un mensaje de error.


Título: Re: vb6 es tonto
Publicado por: BlackZeroX en 2 Octubre 2011, 01:26 am
.
Es BlackZeroX... no BlackZero ¬¬"

Lo probaste compilado?...

Dulces Lunas!¡.


Título: Re: vb6 es tonto
Publicado por: 79137913 en 2 Octubre 2011, 01:33 am
HOLA!!!

Es cierto, Pero no es noticia :S

Cuento viejo...

Pero... proba compilando en Otros modos de compilacion.

GRACIAS POR LEER!!!


Título: Re: vb6 es tonto
Publicado por: Psyke1 en 2 Octubre 2011, 01:44 am
Sí, probé compilado. :P
Yo también sabía esto de hace tiempo, pero ingenuo de mí, llegué a pensar que en todos los lenguajes era igual. :laugh:
Y la gente que no programa en vb6 no lo suele saber, así que no creo que esto haya sido 100% en vano.

DoEvents! :P


Título: Re: vb6 es tonto
Publicado por: Yoghurt en 8 Octubre 2011, 00:27 am
No han escuchado por ahí o leído de que VB comprueba desde la izquierda hacia la derecha??

Por ejemplo en:
If (A=True) Or (B=False) Then ...

Comprueba si B=False y Luego si A=True. Eso lo tengo en mi memoria hace unos años que leí eso. Aunq me da flojera comprobarlo, ahora que salió el tema a la "parrilla" :)

P.D.: Siempre se ha sabido de las falencias de la Microsoft con Todos sus productos, aunq ya deberían saberlo y da risa cuando sale uno alegando por los defectos =D


Título: Re: vb6 es tonto
Publicado por: $Edu$ en 8 Octubre 2011, 16:29 pm
Eso si q no xD, lee de izquierda a derecha es decir primero A y luego B, y esto que se habla aca no son "defectos" sino que no tiene la capacidad de elegir cuando usar And comun y cuando no, en cambio vb.net si lo tiene.

Con este codigo se van todas las dudas.

Código
  1. Private Sub Form_Load()
  2. If (EnLinea("Nestor")) And (EnLinea("edu")) Then
  3. MsgBox "Imposible que aparezca este mensaje!"
  4. End If
  5. End Sub
  6.  
  7. Private Function EnLinea(ByVal contacto As String) As Boolean
  8.  
  9. If contacto = "edu" Then
  10.    MsgBox "Edu siempre esta online xD" ' entonces da true
  11. Else
  12.    MsgBox "No esta conectado!"
  13.    Exit Function
  14. End If
  15.  
  16. EnLinea = True
  17.  
  18. End Function
  19.  


Título: Re: vb6 es tonto
Publicado por: Sanlegas en 8 Octubre 2011, 21:39 pm
Me imagino que ha de comprobar las demas condiciones por si hay otro operador logico que pueda comprobar, como un XOR, ejemplo:

Código
  1. Option Explicit
  2.  
  3. Private Function OrTest(ByVal bReturn As Boolean) As Boolean
  4.    '// Imprimo un texto para saber que he pasado por la función.
  5.    Debug.Print Time$, "Función con el argumento " & bReturn & " llamada."
  6.    OrTest = bReturn
  7. End Function
  8.  
  9. Private Sub Form_Load()
  10.  
  11.    '// Aquí lo logico sería comprobar las dos ya que
  12.    '// si la primera no es true, lo puede ser la segunda.
  13.    If OrTest(False) Or OrTest(False) Then
  14.        '// Nothing
  15.    End If
  16.  
  17.    Debug.Print String$(75, "=")
  18.  
  19.    If OrTest(True) Or OrTest(False) Xor OrTest(True) Then
  20.        Debug.Print "OK!"
  21.        '// Nothing
  22.    End If
  23. End Sub

Como dicen ustedes con la primera comparación tendria que salirse e imprimir "OK!", pero como el XOR da false no lo imprime, salu2 !


Título: Re: vb6 es tonto
Publicado por: seba123neo en 8 Octubre 2011, 23:07 pm
No sabias esto de antes? :S hasta yo lo sabia xD

En .net por ejemplo ya tienes opcion, si quieres un "Or" comun como en vb6 o un "Or" mas "rapido" que saldra si ya no cambiara en nada las siguientes condiciones con el final.

AndAlso y OrElse en .NET son operaciones cortocircuitadas, asi como el operador ternario de java "?"


Título: Re: vb6 es tonto
Publicado por: $Edu$ en 9 Octubre 2011, 15:00 pm
Gracias seba, y Tenient.. el mensaje "OK!" saldra SOLAMENTE si el la condicion es verdadera, y como dices es falsa entonces obvio que no entra, lo que estamos diciendo es que sea True o False la condicion, pasara uno por uno, en este caso tiene que mirar todos obligado por el xor que pusiste pero deciamos en caso como if true or true or true or true or true or true or true..., con el primero ya da True la condicion y no necesitaria comprobar todos los otros, pero si lo hace, pero en .net como dice seba existe el OrElse que no va a verificar el resto de las condiciones ya que no cambiaran el resultado.


Título: Re: vb6 es tonto
Publicado por: Sanlegas en 12 Octubre 2011, 07:10 am
Gracias seba, y Tenient.. el mensaje "OK!" saldra SOLAMENTE si el la condicion es verdadera, y como dices es falsa entonces obvio que no entra, lo que estamos diciendo es que sea True o False la condicion, pasara uno por uno, en este caso tiene que mirar todos obligado por el xor que pusiste pero deciamos en caso como if true or true or true or true or true or true or true..., con el primero ya da True la condicion y no necesitaria comprobar todos los otros, pero si lo hace, pero en .net como dice seba existe el OrElse que no va a verificar el resto de las condiciones ya que no cambiaran el resultado.

Exactamente... solo con los OR pasa, y no con todas las condiciones o que sea algo común del VB, salu2  :D


Título: Re: vb6 es tonto
Publicado por: skapunky en 12 Octubre 2011, 12:04 pm
No estoy deacuerdo con ustedes....la visión de que si A es TRUE no deba leer B es errónea, lo que no seria lógico de parte del programador es:
Citar
If A = True Or A = False Then  [Siempre se cumple]

Lo que ustedes plantean:

Citar
If A = True Or B = False Then

Es válido totálmente y el compilador da igual si lo interpreta de izquierda a derecha o viceversa. Fíjense que A y B són independientes y el estado TRUE/FALSE simplemente es un boolean.

Lo que planteo esque quizá haya una situación que para que se de mediante el IF, A deba ser cierta y B falsa siendo entre ellas independientes. Si fueran dependientes entonces la construcción debe ser otra pero no es culpa del compilador, es del programador.

Por cierto:

Citar
Código:
If Calculo(1) Or Calculo(2) Or Calculo(3) Or Calculo(4) Or Calculo(5) Then
    '...
End If

Para algo inventaron el "SWITCH" o en el caso de vb el "CASE"


Título: Re: vb6 es tonto
Publicado por: $Edu$ en 12 Octubre 2011, 15:37 pm
Tenient y skapunky, estan entendiendo mal.

Lo que hablamos es simple, no hablamos del resultado que da la condicion, sino simplemente hablamos que recorre todas ya sabiendo que no cambiara el resultado final.

Código
  1. If Calculo(1) Or Calculo(2) Or Calculo(3) Or Calculo(4) Or Calculo(5) Then
  2.    '...
  3. End If
  4.  

Si Calculo() es una funcion que devuelve True O False pero a la vez nos manda un msgbox para avisarnos del error o de la verificacion de que todo esta bien.. con que el primer Calculo(1) sea true, nos mostrara nuestro mensaje "OK" pero luego verifica los otros "en vano" ya que la condicion sera True de todos modos, y en que nos perjudica? en que nos mostrara en este caso 4 msgbox mas, ya sean de "OK" o de "Error". Pero esta bien eso, ya que a veces talvez necesitamos que lea esas funciones de todos modos, pero a veces no, y por eso en .net estan los "Or" y los "OrElse" que este ultimo, cuando ya 1 condicion se dio True, ya no lee las otras, entonces ahora con .net tenemos la opcion de cuando queremos que lea todas las condiciones y cuando no ;) Pero en vb6 tenemos el "Or" comun solamente :/

Lo mismo es para And, que en .net existe AndAlso para que si el primero ya da False, que no siga leyendo los demas.


Título: Re: vb6 es tonto
Publicado por: Hurubnar en 12 Octubre 2011, 16:42 pm
Citar
Si Calculo() es una funcion que devuelve True O False pero a la vez nos manda un msgbox para avisarnos del error o de la verificacion de que todo esta bien.. con que el primer Calculo(1) sea true, nos mostrara nuestro mensaje "OK" pero luego verifica los otros "en vano" ya que la condicion sera True de todos modos, y en que nos perjudica? en que nos mostrara en este caso 4 msgbox mas, ya sean de "OK" o de "Error".
En absoluto. Nos perjudica en que tarda más tiempo comprobando la función. Es decir, tenemos el siguiente código:

Código
  1. If var0 = "1" Or var1 = "1" Or var2 = "1" Then
  2.    msgbox "El mensaje"
  3. End If
  4.  
Si únicamente var0 contiene el valor "1" nos mostrará el mensaje una sola vez pero también comprobará (malgastando tiempo) los valores de var1 y var2.

En cambio, si las tres variables contienen el valor "1", según tú nos mostrará el mensaje tres veces. Por el contrario, nos mostrará el mensaje una sola vez, insisto, esto nos afecta únicamente en que tarda más tiempo en comprobar la función.

Un saludo,
atte. Herio


Título: Re: vb6 es tonto
Publicado por: $Edu$ en 12 Octubre 2011, 23:16 pm
Me rindo, que alguien que me haya entendido que lo explique xDD o lee tranquilo desde el primer post hacia abajo, probando los codigos, etc xD