¿hay alguna función "StringToEnum" o una alternativa? - página 2

 

He estado siguiendo esto pero no tengo claro qué es exactamente lo que quieres lograr.

Suelo recodificar las cosas haciéndolas de diferentes maneras para terminar con el resultado final que buscaba, las cosas se pueden hacer de muchas maneras.

 
Marco vd Heijden:

He estado siguiendo esto pero no tengo claro qué es exactamente lo que quieres lograr.

Suelo recodificar las cosas haciéndolas de diferentes maneras para terminar con el resultado final que buscaba, las cosas se pueden hacer de muchas maneras.

Gracias Marco. Por supuesto que las cosas se pueden hacer de muchas maneras (y soluciones), a veces tienes que elegir una de ellas para lograr tu objetivo, pero hay algunas maneras más fáciles que otras. En este caso la solución que tomé para imitar la función StringToEnum estaba usando múltiples comparaciones de cadenas con "if", pero como dije antes la función eval (no implementada en mql5) podría ayudar a evitar todos esos if, y también ayudar en el mantenimiento porque si las constantes cambian de nombre entonces no tienes que cambiar el bloque de ifs.
 

Sé exactamente lo que quieres decir, tengo cientos, a veces incluso miles de líneas if en un bloque de código para llegar a lo que necesito.

tienes que amar lo que haces.

 
cyberglassed:
Gracias Marco. Por supuesto que las cosas se pueden hacer de muchas maneras (y workarounds), a veces hay que elegir una de ellas para lograr el objetivo, pero hay algunas maneras más fáciles que otras. En este caso la solución que tomé para imitar la función StringToEnum estaba usando múltiples comparaciones de cadenas con "if", pero como dije antes la función eval (no implementada en mql5) podría ayudar a evitar todos esos if, y también ayudar en el mantenimiento porque si las constantes cambian de nombre entonces no tienes que cambiar el bloque de ifs.

Puedes explicar por favor, por qué necesitas este StringToEnum. Obviamente tienes una cadena con un valor de enum, pero ¿por qué está en una cadena? Tengo curiosidad por saberlo.

En otras palabras, con el apoyo de la función eval(...) podríamos resolver muchas cosas al mismo tiempo.

Eso no ocurrirá NUNCA, no pierdas el tiempo con eso. La función Eval() es una puerta abierta a las fugas de seguridad, Metaquotes no añadirá dicha función.

 
Marco vd Heijden:

Sé exactamente lo que quieres decir, tengo cientos, a veces incluso miles de líneas if en un bloque de código para llegar a lo que necesito.

tienes que amar lo que haces.

Tu problema NO se puede resolver con un StringToEnum(), ya lo sabes (creo).
 
Alain Verleyen:
Tu problema NO se puede resolver con un StringToEnum(), ya lo sabes (creo).

Correcto pero se puede hacer al revés.

  int b=0;
  
  if(EnumToString(MODE_SMMA)=="MODE_SMMA"){b=2;Print("b= ",b);}

Pero no tendría sentido ya que MODE_SMMA ya tiene valor entero 2 por eso escribí que no entiendo lo que cyberglassed está tratando de lograr.

 
Marco vd Heijden:

Correcto pero se puede hacer al revés.

Pero no tendría sentido ya que MODE_SMMA ya tiene valor entero 2 por eso escribí que no entiendo lo que cyberglassed está tratando de lograr.

Marco la solución que uso es algo como lo siguiente (versión muy minimalista):

int StringToEnum(string strId) {
        if (false) {}
        else if (strId == "PRICE_CLOSE")     return 1;
        else if (strId == "PRICE_OPEN")      return 2;
        else if (strId == "PRICE_HIGH")      return 3;
        else if (strId == "PRICE_LOW")       return 4;
        else if (strId == "PRICE_MEDIAN")    return 5;
        else if (strId == "PRICE_TYPICAL")   return 6;
        else if (strId == "PRICE_WEIGHTED")  return 7;
        // ...
        return -1;
}

void OnStart() {
        string strId = "PRICE_MEDIAN";
        printf("%s: %d ", strId, StringToEnum(strId));
}

por supuesto no parto de la constante, parto de una cadena, te digo esto porque en tu código escribiste lo siguiente:

EnumToString(MODE_SMMA)

como si tuvieras desde el principio la propia constante.

Perdona si te he entendido mal, mi inglés no es demasiado bueno.

Saludos.

 
Alain Verleyen:

¿Puede explicar por favor, por qué usted necesita este StringToEnum. Obviamente, usted tiene una cadena con un valor de enum, pero ¿por qué es en una cadena? Tengo curiosidad por saberlo.

En otras palabras, con el apoyo de la función eval(...) podríamos resolver muchas cosas al mismo tiempo.

Eso NUNCA sucederá, no pierdas tu tiempo con eso. La función Eval() es una puerta abierta a las fugas de seguridad, Metaquotes no añadirá dicha función.

Hola Alain, satisfago tu curiosidad :P

Imagina que estás usando múltiples códigos externos mql5, entonces estás tratando con múltiples tipos de datos "enum" definidos en ellos, y por supuesto, como un humano, es mejor para ti recordar el nombre de la cadena de cada valor de cada "enum". Entonces en alguna parte quieres especificar algún valor de algún "enum" en formato de cadena, entonces no puedes hacerlo directamente, así que tienes que usar alguna solución como la que escribí arriba. Esto tiene dos grandes desventajas, la primera es que tienes que recoger todos los valores de todos los enums involucrados y la segunda desventaja es el mantenimiento, por lo que si actualizas algún código mql5 externo donde el desarrollador cambió el valor int asociado a alguna representación constante, entonces podrías obtener un comportamiento inesperado, por lo que tienes que seguir inspeccionando las actualizaciones en el código.

Sobre el tema de las fugas de seguridad... No estoy totalmente de acuerdo con lo que dices de que es una puerta abierta a las fugas de seguridad. Por supuesto que puede ser una puerta abierta, pero tú como programador tienes que establecer los límites y cuidar de posibles situaciones críticas, quiero decir que puedes manejar perfectamente tales situaciones como en PHP, incluso en SQL con inyección de código donde tienes que analizar algunos posibles datos de entrada críticos de los usuarios en caso de que tengan acceso a tu código.

Tal vez en el futuro tengamos un poco de suerte y el equipo de desarrolladores pueda darnos algo de ayuda en esta dirección, así que por ahora, podemos usar soluciones de trabajo :P

 
cyberglassed:

Marco la solución que uso es algo como lo siguiente (versión muy minimalista):

por supuesto no parto de la constante, parto de una cadena, te digo esto porque en tu código escribiste lo siguiente:

como si tuvieras desde el principio la propia constante.

Perdona si te he entendido mal, mi inglés no es demasiado bueno.

Saludos.

Por eso se llama al revés y se empieza comparando todas las enumeraciones para disolver el valor del enum de la cadena.

int b;
if(EnumToString(MODE_SMA)=="MODE_SMA"){b=0;}
if(EnumToString(MODE_EMA)=="MODE_EMA"){b=1;}
if(EnumToString(MODE_SMMA)=="MODE_SMMA"){b=2;}
if(EnumToString(MODE_LWMA)=="MODE_LWMA"){b=3;}

Print(b);


¿pero no es lo mismo?

no importa en que lado se compare la cadena si hay una coincidencia se firmará el valor a b.

int b;
if("MODE_SMA"==EnumToString(MODE_SMA)){b=0;}
if("MODE_EMA"==EnumToString(MODE_EMA)){b=1;}
if("MODE_SMMA"==EnumToString(MODE_SMMA)){b=2;}
if("MODE_LWMA"==EnumToString(MODE_LWMA)){b=3;}

Print(b);

así que aquí empezamos con un valor de cadena pero ¿cuál es la diferencia?

Ninguna.

 
Marco vd Heijden:

...

¿pero no es lo mismo?

no importa en que lado compares la picadura si hay una coincidencia firmará el valor a b.

int b;
if("MODE_SMA"==EnumToString(MODE_SMA)){b=0;}
if("MODE_EMA"==EnumToString(MODE_EMA)){b=1;}
if("MODE_SMMA"==EnumToString(MODE_SMMA)){b=2;}
if("MODE_LWMA"==EnumToString(MODE_LWMA)){b=3;}

Print(b);

así que aquí empezamos con un valor de cadena pero ¿cuál es la diferencia?

Ninguna.

tu código de arriba es inútil porque siempre devolverá "b = 3" (último "if" porque no estás usando "else if")

si usas "else if", entonces siempre devolverá "b = 0".

de todos modos, la información: "b = 3" cada vez, no da ninguna información.

Razón de la queja: