tags:

views:

112

answers:

5

Im trying to code my own DSL for file manipulation, just for the sake of learning.

My goal is to make it understandable and easy to code.

Here are 3 alternatives for appending a string to a database.yml:

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"

Im a little bit lost in all these alternatives.

Could someone with experience in DSL give me some guidance and explain what the pros and cons are with each one?

Everyone are read the same, but I want to know which one follows best practice for DRY and good coding standard.

EDIT: I think it will be good if I could specify some optional parameters eg.

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

So taken this into account, I guess that I have to use the method calls. Because if I use alternatives 4-5 then when I specify :force => true, I can't know if it's for the string or the file.

+3  A: 

Tthe best DSL I know of usually take care of the type for you. So I would not specify the type of the value to appended. This would exclude all alternatives that include the word "string", and maybe also all the alternatives that include the word "file".

I personally like these ones :

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"

if I use alternatives 4-5 then when I specify :force => true, I can't know if it's for the string or the file.

I don't see it as a problem, the optional parameters usually aim at the action. They are neither specific to the string or the file. When you set :force => true, you are forcing the appending.

David
Variants 3-6 look as if the filename is optional, which doesn't seem like a good idea.
Mladen Jablanović
Actually, none of the alternatives proposed on this page force the user to set the target file. I think that's one of the problems with DSL : you can't make sure the user speak the language correctly, as you can't make sure Stack Overflow users will speak english correctly...
David
If you look at Cucumber's DSL, object.property.should == "something", the "== 'something'" can look optionnal. However, the sentence does not seems correct when there's nothing after the should. In the same way as the sentence does not look correct when you try to append some text to nothing.
David
+2  A: 

I think it all depends on how you want to use your DSL. It seems reasonable that one would want to perform several options on a single file in a run, so perhaps you could consider something like

on 'database.yaml' do
  append 'windows'

  line 16 do
    indent 2.spaces
  end

  lines 3,6,7 do
    delete
  end
end

Meaning that first you define a scope (a file, a line, a set of lines, a block etc), and then a set of operations to perform on it. But, then again, we are programmers, perhaps "average user" would like to use something more resembling a natural language, as you have started.

Mladen Jablanović
+3  A: 

For me, any option seems fine.

If you(or user) always write to "database.yml" but appending contents are different, following may better.

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

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

If you(or user) want to append "windows" always for different database files, following may be fine. (Maybe rare case,,)

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

Anyway, I think better choice is to use it yourself or ask your user, then refine.

kyab
+1  A: 

Hi, I write a blog post on DSL's yesterday, it doesn't answer your filesystem-specific DSL question but it should provide you with enough information to make a decision

Slick code with simple DSLs thanks to Ruby

clocKwize
great post! ill bookmark it! is block[email] the same as yield(email)?
never_had_a_name
+1  A: 

some ideas:

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
Ragmaanir