适当的DSL语法

时间:2010-08-19 06:02:35

标签: ruby dsl

我试图编写自己的DSL进行文件操作,只是为了学习。

我的目标是使其易于理解且易于编码。

以下是将字符串附加到database.yml:

的3种方法
1. append("windows").to("database.yml")

2. append(string: "windows").to(file: "database.yml")

3. append_string("windows").to_file("database.yml")

4. append_string "windows", to_file: "database.yml"

5. append string: "windows", to_file: "database.yml"

我在所有这些替代方案中都有点迷失。

有DSL经验的人能给我一些指导并解释每个人的利弊吗?

每个人的阅读都是一样的,但我想知道哪一个遵循DRY的最佳实践和良好的编码标准。

编辑:我认为如果我可以指定一些可选参数,例如

,那将是件好事
append(string: "windows").to(file: "database.yml", :force => true)

因此考虑到这一点,我想我必须使用方法调用。因为如果我使用替代品4-5然后我指定:force =>是的,我不知道它是否是字符串或文件。

5 个答案:

答案 0 :(得分:4)

对我来说,任何选择似乎都没问题。

如果您(或用户)始终写入“database.yml”但附加内容不同, 以下可能更好。

on "database.yml" {
    append "windows"
    append "ubuntsu"
    append "Leopard" 

    remove_if "bsd"  do |..|
         ....#if condition satisfied, "bsd" will be removed
    end
    ..
}

如果您(或用户)想要为不同的数据库文件追加“windows”, 以下可能没问题。 (也许是罕见的情况,)

append "windows".to {
    to "database.yml"
    to "database2.yml"
    to "database3.xml", :force=>true
}

无论如何,我认为更好的选择是自己使用它或询问你的用户,然后改进。

答案 1 :(得分:3)

我所知道的最好的DSL通常会为您处理类型。所以我不会指定要追加的值的类型。这将排除包含“string”一词的所有替代方案,也可能包括所有包含“file”一词的替代方案。

我个人喜欢这些:

append("windows").to("database.yml")
append("windows").to("database.yml", :force => true)

append "windows", :to => "database.yml"
append "windows", :to => "database.yml", :force => true

append "windows", :to_file => "database.yml" # if you really want "to_file"
append "windows", :to_file => "database.yml", :force => true # if you really want "to_file"
  

如果我使用替代品4-5那么当我   指定:force =>是的,我不知道   如果它是字符串或文件。

我不认为这是一个问题,可选参数通常以行动为目标。它们既不特定于字符串也不特定于文件。当你设置:force =>是的,你正在强迫追加。

答案 2 :(得分:3)

我认为这完全取决于您希望如何使用DSL。一个人想要在一个运行中对一个文件执行几个选项似乎是合理的,所以也许你可以考虑像

这样的东西
on 'database.yaml' do
  append 'windows'

  line 16 do
    indent 2.spaces
  end

  lines 3,6,7 do
    delete
  end
end

这意味着首先定义一个范围(一个文件,一行,一组行,一个块等),然后是一组要对其执行的操作。但是,再一次,我们是程序员,也许“普通用户”想要使用更像自然语言的东西,就像你已经开始的那样。

答案 3 :(得分:2)

我昨天写了一篇关于DSL的博客文章,它没有回答你的文件系统特定的DSL问题,但它应该为你提供足够的信息来做出决定

Slick code with simple DSLs thanks to Ruby

答案 4 :(得分:1)

一些想法:

with file('database.yaml') do |f|
  f.append file('additions.yaml')
  f.append 'somekey: true'
  f.move_to dir('/some/where')
  cpy = f.copy_to dir('some/where/else')
  f.delete
end