我试图编写自己的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 =>是的,我不知道它是否是字符串或文件。
答案 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问题,但它应该为你提供足够的信息来做出决定
答案 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