Foros del Web » Programando para Internet » Javascript »

Sobrescribir palabras clave como métodos

Estas en el tema de Sobrescribir palabras clave como métodos en el foro de Javascript en Foros del Web. Buenas, Estos días, para practicar un poco con los conocimientos de Javascript que he ido aprendiendo, he creado una clase DOMAutomat que va modificando elementos ...
  #1 (permalink)  
Antiguo 20/01/2014, 13:50
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 18 años, 4 meses
Puntos: 32
Sobrescribir palabras clave como métodos

Buenas,

Estos días, para practicar un poco con los conocimientos de Javascript que he ido aprendiendo, he creado una clase DOMAutomat que va modificando elementos del DOM a ciertos intervalos de tiempo y en función de un objeto que contiene las instrucciones. Dicho objeto representa unas instrucciones similares al ensamblador por tener saltos condicionales e incondicionales. Luego he creado otra clase Compiler que a través de llamadas a métodos, va construyendo el objeto que luego recibirá DOMAutomat. Y ahí viene el problema. Para que esos métodos sean sugerentes con lo que hacen les he dado nombres como while, if o else que son palabras clave. Aquí dejo el código de interés:

Código Javascript:
Ver original
  1. cc
  2.     .var({
  3.         '$cells'  : cells    ,
  4.         '$i'      : 0        ,
  5.         '$j'      : undefined,
  6.         '$prev'   : undefined,
  7.         '$cur'    : undefined,
  8.         '$flag'   : true     ,
  9.         '$bgClass': 'bg-red'
  10.     })
  11.     .action([
  12.         // accion nula
  13.     ])
  14.     .while( "$i < 4" )
  15.         .calc( "$j = 0" )
  16.         .while( "$j < 4" )
  17.             .calc( "$cur = $cells[$i][$j]" )
  18.             .if( "$flag" )
  19.                 .action( [
  20.                     ["$prev", removeClass, ["$bgClass"] ],
  21.                     ["$cur" , addClass   , ["$bgClass"] ]
  22.                 ])
  23.                 .if( "$cur.classList.contains('bg-blue')" )
  24.                     .action([
  25.                         ["$cur", removeClass, ["$bgClass"] ]
  26.                     ])
  27.                     .calc(
  28.                         "$bgClass = $bgClass === 'bg-red' ? 'bg-green' : 'bg-red';" +
  29.                         "$flag = false;"
  30.                     )
  31.                     .action([
  32.                         ["$cur", addClass, ["$bgClass"] ]
  33.                     ])
  34.                 .end()
  35.                 .calc( "$prev = $cur" )
  36.             .else()
  37.                 .calc( "$flag = true" )
  38.             .end()
  39.             .calc( "++$j" )
  40.         .end()
  41.         .calc( "++$i" )
  42.     .end()
  43.     .action([
  44.         ["$prev", removeClass, ["$bgClass"] ]
  45.     ]);
  46.     console.log( cc.code );
  47.  
  48.     // crea un autamata que ejecuta una acción cada segundo
  49.     var domAutomat = new DOMAutomat(1000);
  50.     // asigna el codigo al automata
  51.     domAutomat.setCode( cc.code );
  52.     // pone en ejecución el automata
  53.     domAutomat.run();

Y aquí el enlace con todo el código y el resultado:
http://jsfiddle.net/jefebrondem/ny7Ky/

Tengo dos dudas. La principal es si sobrescribir métodos con palabras clave lo soporta el estándar. Pues, por ejemplo, a mi chrome me lo permite pero puedo asegurar que cualquier navegador que siga el estándar me lo permitirá. No he encontrado información al respecto.

La otra duda es más de diseño, yo en este caso me he visto inevitablemente forzado a usar el constructor Function para ganar en expresividad. Antes de usar el constructor Function el código con while's e if's lo simulaba con un objeto literal quedando algo de este estilo:
Código Javascript:
Ver original
  1. var code = [
  2.         { 'var' : {
  3.             'i'      : 0        ,
  4.             'j'      : undefined,
  5.             'prev'   : undefined,
  6.             'cur'    : undefined,
  7.             'flag'   : true     ,
  8.             'bgClass': 'bg-red'
  9.         }},
  10.         { 'action': function() { return [
  11.             //acción nula
  12.         ]}},
  13.         { 'while': [ function(){ return this.i < 4; },
  14.             function(){
  15.                 this.j = 0;
  16.             },
  17.             { 'while' : [ function(){ return this.j < 4; },
  18.                 function(){
  19.                     this.cur = cells[this.i][this.j];
  20.                 },
  21.                 { 'if': [ function(){ return this.flag; },
  22.                     { 'action': function() { return [
  23.                         [this.prev, removeClass, [this.bgClass] ],
  24.                         [this.cur , addClass   , [this.bgClass] ]
  25.                     ]}},
  26.                     { 'if': [ function(){ return this.cur.classList.contains('bg-blue'); },
  27.                         { 'action': function() { return [
  28.                             [this.cur, removeClass, [this.bgClass] ],
  29.                         ]}},
  30.                         function(){
  31.                             this.bgClass = this.bgClass === 'bg-red' ? 'bg-green' : 'bg-red';
  32.                             this.flag = false;
  33.                         },
  34.                         { 'action': function() { return [
  35.                             [this.cur, addClass, [this.bgClass] ],
  36.                         ]}},
  37.                     ]},
  38.                     function(){
  39.                         this.prev = this.cur;
  40.                     }
  41.                 ],'else': [
  42.                     function(){
  43.                         this.flag = true;
  44.                     }
  45.                 ]},
  46.                 function(){
  47.                     ++this.j;
  48.                 },
  49.             ]},
  50.             function(){
  51.                 ++this.i;
  52.             }
  53.         ]},
  54.         { 'action': function() { return [
  55.             [this.prev, removeClass, [this.bgClass] ]
  56.         ]}}
  57.     ]
http://jsfiddle.net/jefebrondem/aexE7
De esta manera no he usado el constructor Function, pero el código es más dicifil de escribir y, con ello, más propenso a escribirlo mal.
¿Alguien sabría de alguna manera más simple de representación sin tener que echar mano al contructor Function o a eval?

Un saludo y gracias.
__________________
github.com/xgbuils | npm/xgbuils
  #2 (permalink)  
Antiguo 20/01/2014, 15:15
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 10 meses
Puntos: 206
Respuesta: Sobrescribir palabras clave como métodos

El autómata que has hecho concatenando órdenes mediante chaining marea con sólo verlo xd.

Que yo sepa, no se recomienda usar como identificador ninguna palabra reservada.
Así que la pregunta es ¿es el nombre de cualquier atributo o método de un objeto, un identificador? Pues al parecer no, porque el parseador léxico que trocea el código por tokens no interpreta igual un var for=4; que un array["for"]=4 o lo que es lo mismo, array.for

En cuanto a eval y Function, son las dos únicas formas que conocía de interpretar una cadena como si fuera código real de forma automática. Quedaría como ya sabrás la tercera vía: Trocear y evaluar manualmente la cadena.
  #3 (permalink)  
Antiguo 21/01/2014, 14:19
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 18 años, 4 meses
Puntos: 32
Respuesta: Sobrescribir palabras clave como métodos

Cita:
Iniciado por marlanga
El autómata que has hecho concatenando órdenes mediante chaining marea con sólo verlo xd.
jaja, pues comparado con mis anteriores prototipos yo lo veo bastante leíble. Supongo que será porque lo he hecho yo y ya me he acostumbrado... De todas formas lo he mejorado un poco incluyendo el for entre otras cosas:
Código Javascript:
Ver original
  1. var cc = new Compiler();
  2.  
  3.     cc
  4.     .var( '$cells'  , cells   )
  5.     .var( '$flag'   , true    )
  6.     .var( '$bgClass', 'bg-red')
  7.     .var( '$i', '$j', '$prev', '$cur' )
  8.     .action(
  9.         // accion nula
  10.     )
  11.     .for( "$i=0", "$i < 4", "++$i" )
  12.         .for( "$j = 0", "$j < 4", "++$j" )
  13.             .calc( "$cur = $cells[$i][$j]" )
  14.             .if( "$flag" )
  15.                 .action(
  16.                     ["$prev", removeClass, ["$bgClass"] ],
  17.                     ["$cur" , addClass   , ["$bgClass"] ]
  18.                 )
  19.                 .if( "$cur.classList.contains('bg-blue')" )
  20.                     .action(
  21.                         ["$cur", removeClass, ["$bgClass"] ]
  22.                     )
  23.                     .calc(
  24.                         "$bgClass = alternate($bgClass, 'bg-red', 'bg-green')",
  25.                         "$flag = false"
  26.                     )
  27.                     .action(
  28.                         ["$cur", addClass, ["$bgClass"] ]
  29.                     )
  30.                 .end()
  31.                 .calc( "$prev = $cur" )
  32.             .else()
  33.                 .calc( "$flag = true" )
  34.             .end()
  35.         .end()
  36.     .end()
  37.     .action(
  38.         ["$prev", removeClass, ["$bgClass"] ]
  39.     );
http://jsfiddle.net/jefebrondem/ny7Ky/1/

Cita:
Iniciado por marlanga
En cuanto a eval y Function, son las dos únicas formas que conocía de interpretar una cadena como si fuera código real de forma automática. Quedaría como ya sabrás la tercera vía: Trocear y evaluar manualmente la cadena.
Esto es lo que me temía. El problema es que si las instrucciones las paso a través de un string para luego parsearlo, el código en un editor de código será monocolor, no habrá control de cierre de paréntesis, cosa que no facilita la escritura de código para el autómata.

Otra cosa que se me ocurre es hacer un programa preprocesador que lea un texto pseudojavascript con la escritura del código del autómata y lo convierta en un código javascript listo para funcionar.

Las dos me dan un poco de palo, porque es ponerse en el meollo de hacer una especie de compilador medianamente serio para un nuevo lenguaje. Así que si no hay más alternativas creo que de momento me quedaré con el encadenamiento de funciones que, así, sólo tendré que parsear pequeñas cadenas y olvidare de gramáticas libres de contexto.

Un saludo y gracias!
__________________
github.com/xgbuils | npm/xgbuils

Última edición por Pantaláimon; 21/01/2014 a las 14:28
  #4 (permalink)  
Antiguo 21/01/2014, 15:45
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 10 meses
Puntos: 206
Respuesta: Sobrescribir palabras clave como métodos

Ya que te gusta haskell, y siempre quieres ir un poco mas allá, échale un vistazo a http://coffeescript.org/
  #5 (permalink)  
Antiguo 24/01/2014, 12:07
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 18 años, 4 meses
Puntos: 32
Respuesta: Sobrescribir palabras clave como métodos

Gracias marlanga. Me lo apunto.
__________________
github.com/xgbuils | npm/xgbuils

Etiquetas: constructor, eval, function, keywords
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 12:59.