JavaScript DSLの例


DSL(domain-specific languages)は分野の特定の言語であり、DSLの境界を特定できる唯一の方法は「一つの言語の特定の使い方」と「その言語の設計者や使用者の意図を考慮することである.DSLを設計しようとすると、いくつかの興味深い簡単な例が発見された.
jQueryで一番流行っているDSL
jQueryはInternal DSLの典型的な例である.これは、既存の言語内で分野の問題に対する記述を実現するものです.
$('.mydiv').addClass('flash').draggable().css('color', 'blue')

これが最も有名なチェーンメソッド呼び出しです.
Cucumber.js
Cucumber, the popular Behaviour-Driven Development tool, brought to your JavaScript stack.この分野を汎用言語で記述する問題です.
Feature: Example feature
  As a user of cucumber.js
  I want to have documentation on cucumber
  So that I can concentrate on building awesome applications

  Scenario: Reading documentation
    Given I am on the Cucumber.js GitHub repository
    When I go to the README file
    Then I should see "Usage" as the page title

CoffeeScript
新しい言語を発明してこの分野の問題を説明する.
math =
  root:   Math.sqrt
  square: square
  cube:   (x) -> x * square x

JavaScript DSLの例
以上の結論から分かるように、難易度は
内部DSL<外部DSL<言語ワークベンチ(これはどのように翻訳されていますか)
次に、jQuery式のチェーンメソッド呼び出しを行うのも簡単ですが、他の人を説得するのに十分な理由がないようです.
原文は次のとおりです.http://alexyoung.org/2009/10/22/javascript-dsl/マイクロテストフレームワークに相当します
var DSLRunner = {
  run: function(methods) {
    this.ingredients = [];
    this.methods     = methods;

    this.executeAndRemove('first');

    for (var key in this.methods) {
      if (key !== 'last' && key.match(/^bake/)) {
        this.executeAndRemove(key);
      }
    }

    this.executeAndRemove('last');
  },

  addIngredient: function(ingredient) {
    this.ingredients.push(ingredient);
  },

  executeAndRemove: function(methodName) {
    var output = this.methods[methodName]();
    delete(this.methods[methodName]);
    return output;
  }
};

DSLRunner.run({
  first: function() {
    console.log("I happen first");
  },

  bakeCake: function() {
    console.log("Commencing cake baking");
  },

  bakeBread: function() {
    console.log("Baking bread");
  },
  last: function() {
    console.log("last");
  }
});

この考えは、mapを定義して実行するように見えます.
次に、興味深いDSLを見ました.著者はフォーム検証の問題「JavaScript DSL Because I’m Tired of Writing If.If...If...」:
 var rules =
    ['Username',
      ['is not empty', 'Username is required.'],
      ['is not longer than', 7, 'Username is too long.']],
    ['Name',
      ['is not empty', 'Name is required.']],
    ['Password',
      ['length is between', 4, 6, 'Password is not acceptable.']]]; 

mapが上記の方法に対応しています
 var methods = [
    ['is not empty', isNotEmpty],
    ['is not longer than', isNotLongerThan],
    ['length is between', isBetween]];

原文は一部のコードしか与えていない
    var methodPair = find(methods, function(method) {
        return car(method) === car(innerRule);
    });

    var methodToUse = peek(methodPair);

    return function(obj) {
        var error = peek(innerRule);                           //error is the last index
        var values = sink(cdr(innerRule));                     //get everything but the error  
        return methodToUse(obj, propertyName, error, values);  //construct the validation call
    };