2009-01-29 3 views
1

Je développe actuellement un site de tutorat pour enseigner les bases du développement Web (HTML, CSS et JavaScript, pour les débutants). Je voudrais une installation où je pourrais couvrir en profondeur toutes sortes de sujets et fournir ensuite un environnement de base de bac à sable où l'utilisateur pourrait écrire du code qui résout la question posée à la fin de chaque section de tutoriel. Par exemple, si j'avais couvert la multiplication dans un précédent tutoriel, et que l'utilisateur venait de terminer une leçon sur les fonctions pouvant renvoyer des valeurs, je pourrais demander qu'elles soumettent une fonction qui renvoie le produit de deux paramètres.Est-ce un cas approprié dans lequel l'utilisation de la création de fonction dynamique serait justifiée?

N'est-ce pas le parfait instance dans laquelle l'utilisation de la création de fonction dynamique serait considérée comme une bonne idée? Regardons un exemple.

<script> 
function check() 
{ 
eval('var f = ' + document.getElementById('user_code').value); 
if (f(5, 10) == 50) 
{ 
// user properly wrote a function which 
// returned the product of its parameters 
} 
} 
</script> 

Est-ce une mauvaise idée? Si oui, veuillez expliquer.

Répondre

1

Cela semble fonctionner. Cependant, le plus gros problème dans votre environnement pourrait être la gestion des erreurs. Les étudiants vont sûrement faire toutes sortes d'erreurs:

  • erreurs de compilation, qui seront détectés dans eval()
  • erreurs de temps d'exécution, qui seront détectés lorsque vous appelez la fonction
  • erreurs de temps d'exécution indétectables, tels comme une boucle infinie ou un débordement de pile

Une approche plus élaborée pourrait analyser le Javascript entré dans une représentation d'arbre d'analyse, puis le comparer à un arbre d'analyse attendu. Si ce n'est pas le cas, signalez ce qui pourrait ne pas être correct et demandez à l'élève de réessayer. Si cela correspond, alors vous pouvez eval() et appelez la fonction, sachant qu'elle fera ce que vous attendez. L'implémentation d'un lexer et d'un parser pour Javascript en Javascript serait difficile mais certainement pas impossible.

1

On dirait que vous voulez refaire Firebug ou même les nouveaux outils de développement dans IE8. Pour cette raison, je dois dire qu'il n'y a jamais de cas utile. Sans parler des possibilités d'injection de script si ce site devient public.

+0

Pas utile du tout, mec ... –

+0

Vous essayez de réinventer la roue. Préférez-vous que je dise simplement non, puisque ce que vous essayez d'accomplir a été fait? – geowa4

+0

Vous n'avez certainement pas lu ma question correctement; J'ai clairement indiqué que j'envisageais d'utiliser cette méthode sur un site Web pour une raison précise. Pourquoi dans le monde serais-je à la recherche d'un outil Firefox seulement qui ne fait même pas ce que je demandais en premier lieu? –

1

Fonctionne aussi longtemps que vous l'utilisez dans un environnement fermé. Eval vous ouvre la porte aux attaques par injection de code, donc je ne mettrais pas cela sur un site web accessible au public, mais s'il est complètement contenu dans votre salle de cours, ça devrait aller.

1

Le code fonctionnerait, mais qu'en est-il s'il y a une erreur syntaxique ou autre? Peut-être utiliser un bloc try pour attraper une erreur et l'afficher à l'utilisateur aiderait les choses un peu ...

Vous ne savez pas si cela aide.

1

Dans votre cas, je pense qu'il n'y a rien de mal à cela. Vous pouvez également exécuter le code en utilisant new Function() pour créer des éléments en premier, puis exécutez-le. En théorie, cela séparerait les étapes de «compilation» et d'exécution. Cependant eval vérifiera le code premier et lancer des erreurs quand même:

var usercode = document.getElementById('user_code').value; 
try { 

    var f = new Function('a','b','return (' + usercode + ')(a,b);'); 
    if (f(5, 10)) { 
    // user properly wrote a function which 
    // returned the product of its parameters 
    } 
    else { 
    // user wrote code that ran but produced incorrect results 
    } 

} 
catch (ex) { 
    // user wrote something really bad 
} 

Le problème de faire les choses de cette manière est que les exceptions peuvent être jetées aucun sens."foo;;=bar" signalera une erreur "entre parenthèses" entre parenthèses alors que eval lancera une erreur de syntaxe de propper. Vous pouvez contourner ceci par (regexp) en saisissant d'abord les paramètres et le corps du code utilisateur, puis en le construisant. Mais alors, comment cela serait-il mieux qu'un eval?

Je pense que votre vrai problème aidera les utilisateurs à éviter les pièges des globales implicites. Comment allez-vous aider les utilisateurs à éviter d'écrire du code qui ne fonctionne que la deuxième fois parce qu'un global a été défini la première fois? N'auras-tu pas besoin de mettre en place un bac à sable propre à chaque passage? Je voudrais voir comment jsbin.com, firebug et autres outils similaires gèrent ces choses.

Mon sentiment est que vous devriez aller avec eval pour l'instant et le changer pour des trucs plus élaborés plus tard si le besoin s'en fait sentir.

Questions connexes