代码之家  ›  专栏  ›  技术社区  ›  egervari

什么可以使这个DSL更容易输入或读取?

  •  3
  • egervari  · 技术社区  · 15 年前

    我已经编写了一个工作语法来替换scala中的dbunit,称为scaladbtest。整个程序工作-只花了2天的时间就完成了。我有很多事情要做。

    总之,我使用的DSL将数据输入数据库的语法是有延展性的,我希望得到一些反馈。

    基本语法如下。很简单:

    country:
    - country_id: 1, name: "Canada"
    - country_id: 2, name: "United States"
    

    这当然比XML或SQL INSERT语句好。

    我讨论过使用“:”或“=”。前者看起来更好,但后者对我来说似乎是自动输入的。

    还有一个概念,您可以在其中“标记”一个记录。在某种意义上,上述语法是匿名记录。标签将是一个有趣的特性,因为您可以以多种方式使用它们。

    country:
        record: Canada -> country_id: 1, name: $label # produces "Canada"
        record: UnitedStates -> country_id: 2, name: $label.uncamel # produces "United States"
    

    我不喜欢这种句法。有点言过其实。使用“—”看起来不正确,但是如果我使用像“record”这样的实际命令词,我需要将“—>”分开,否则看起来非常糟糕(出于技术原因不需要)。

    $label将简单地重复标签,因此您可以使用标签作为重用字符串的最低限度。$label.uncamel将在看起来像骆驼壳的地方添加空格。

    标签背后的想法是为API提供一种访问记录而不必记住ID的方法。如果您知道要获取的国家对象是“Canada”,那么您只需传递标签“Canada”,它就会将其转换为唯一的ID并将其从数据库中拉出。

    下面是一个可以指定默认参数的示例:

    province:
    ? country_id: 1, nice_weather: true
    - province_id: 1, name: "British Columbia"
    - province_id: 2, name: "Manitoba", nice_weather: false
    - province_id: 3, name: "New York", country_id: 2
    

    这是你看到的真正的力量。所有这3个“省”记录都将有4列。由于其中两个省来自加拿大,它们将自动从默认值继承。在第三种情况下,我们用美国代替纽约。我们可以根据需要进行混合/匹配。

    在实践中,这将节省大量的输入和认知负载,因为我们在实践中通常只关心一些值,而其余的值可能仅仅是占位符,以使数据库关闭缺少的必需字段等。这对测试多态对象也很有帮助。

    这里还有一个:

    article:
    ? date_create: $now
    - article_id: 1, title: "The Fed Sucks"
    - article_id: 2, title: null
    

    这段代码说明,您实际上可以放置空值,而不必像在dbunit中那样做任何技巧。在dbunit中,必须首先创建一个转换器,将自定义字符串(如“[空]”)转换为实际空值。

    事实上,我们可以更具表现力,提供各种表达式和函数来帮助生成数据。例如,$now返回今天日期/时间的正确格式的SQL日期。我将扩展这些特性,以帮助简化编写测试数据。

    总之,我正在寻找帮助来真正清理语法。我可以做任何改变,因为这是新鲜的,我想让它从一开始就非常时髦,而不是以后再改变。

    谢谢

    4 回复  |  直到 15 年前
        1
  •  1
  •   XecP277    15 年前

    我将建议以以下方式扩展标签的初始语法:

    1. 按列名排列的段/组标签。
      国家:【标签:名称】
      -国家/地区ID:1,名称:“加拿大”
      -国家编号:2,名称:“美国”
    2. 按列索引对标签进行分段/分组,以最小化键入。
      国家:【标签:2】
      -国家/地区ID:1,名称:“加拿大”
      -国家编号:2,名称:“美国”
    3. 单槽
      国家:
      -[标签:2]国家/地区ID:1,名称:“加拿大”
      -[标签:名称]国家/地区ID:2,名称:“美国”

    如果不想跟踪记录中的列数,可以消除基于索引的标签。

    如果您希望扩展该工具,可以为记录组添加其他属性,如并发性,例如,使用5个线程创建5K行,如下所示:


    国家:【标签:名称】【并发性:5】
    -[标签:2]国家/地区ID:1,名称:“加拿大”
    -[标签:名称]国家/地区ID:2,名称:“美国”

        2
  •  1
  •   retronym    15 年前

    我会考虑将它嵌入到scala中,而不是创建一个外部DSL。有帮助的特性有case类、默认参数、编译器生成的复制方法。

        3
  •  1
  •   Landei    15 年前

    虽然拥有一个易于理解和简洁的格式是很重要的,但是IMHO仍然没有理由不寻找标准化的替代方案就编写自己的专有文件。您是否考虑使用轻量级和可读性更高的XML替代方案,例如 JSON HAML ?注意,如果您只支持定义良好的子集,那么您仍然具有工具支持和标准化的优势。

        4
  •  1
  •   Daniel C. Sobral    15 年前

    这看起来很像 YAML 我建议你看看。以下是一些有效的yaml语法:

    country:
      - country_id: 1
        name: Canada
      - country_id: 2
        name: United States
    
    # country
    ---
    country_id: 1
    name: Canada
    ---
    country_id: 2
    name: United States