How to make this Lua snippet DRY (Don't Repeat Yourself)

I’ve created a form to choose the settings: These settings are automatically saved in a file from the game client in this form:

 

["Setting"] = { ["track"] = "Spell Reflect", ["duration"] = { ["minimum"] = { ["enabled"] = 1, ["value"] = 3, }, ["maximum"] = { }, }, ["stack"] = { ["minimum"] = { }, ["maximum"] = { ["enabled"] = 1, ["value"] = 4, }, }, }

To save the settings in this form I used this function:

 

function UnitScan\_onAdvancedOptionClose() if not (db["duration"]) then db["duration"] = {} db["duration"]["minimum"] = {} db["duration"]["maximum"] = {} end db["duration"]["minimum"].enabled = minduration.cbutton:GetChecked() db["duration"]["minimum"].value = tonumber(minduration.ebox:GetText()) db["duration"]["maximum"].enabled = maxduration.cbutton:GetChecked() db["duration"]["maximum"].value = tonumber(maxduration.ebox:GetText()) if not (db["stack"]) then db["stack"] = {} db["stack"]["minimum"] = {} db["stack"]["maximum"] = {} end db["stack"]["minimum"].enabled = minstack.cbutton:GetChecked() db["stack"]["minimum"].value = tonumber(minstack.ebox:GetText()) db["stack"]["maximum"].enabled = maxstack.cbutton:GetChecked() db["stack"]["maximum"].value = tonumber(maxstack.ebox:GetText()) end

Where

  • db = The “Setting” table
  • GetChecked() = Returns whether the check button is checked
  • GetText() = Returns the edit box’s text contents

Could you help me to make the code less repetitive and more elegant?

I usually prefer readability over brevity, so I think your code is just fine. Suppose some people might prefer something like this:

function UnitScan\_onAdvancedOptionClose() db.duration = { minimum = { enabled = minduration.cbutton:GetChecked(), value = tonumber(minduration.ebox:GetText())}, maximum = { enabled = maxduration.cbutton:GetChecked(), value = tonumber(maxduration.ebox:GetText())} } db.stack = { minimum = { enabled = minstack.cbutton:GetChecked(), value = tonumber(minstack.ebox:GetText())}, maximum = { enabled = maxstack.cbutton:GetChecked(), value = tonumber(maxstack.ebox:GetText())} } end

Just to offer another option.  Though not as concise as _memo’s solution, but it does allow you to easily expand your options list just by adding additional values to the options key.

function UnitScan\_onAdvancedOptionClose() local options = { 'duration', 'stack' } for i=1, #options do local option = options[i] if not db[option] then db[option] = { minimum = {}, maximum = {} } end db[option].minimum = { enabled = ["min"..option].cbutton:GetChecked(), value = tonumber(["min"..option].ebox:GetText()) } db[option].maximum = { enable = ["max"..option].cbutton:GetChecked(), value = tonumber(["max"..option].ebox:GetText()) } end end

Best.

I usually prefer readability over brevity, so I think your code is just fine. Suppose some people might prefer something like this:

function UnitScan\_onAdvancedOptionClose() db.duration = { minimum = { enabled = minduration.cbutton:GetChecked(), value = tonumber(minduration.ebox:GetText())}, maximum = { enabled = maxduration.cbutton:GetChecked(), value = tonumber(maxduration.ebox:GetText())} } db.stack = { minimum = { enabled = minstack.cbutton:GetChecked(), value = tonumber(minstack.ebox:GetText())}, maximum = { enabled = maxstack.cbutton:GetChecked(), value = tonumber(maxstack.ebox:GetText())} } end

This code generate an error:

unexpected symbol near “[”

In correspondence of line 

enabled = [“min”…option].cbutton:GetChecked(),

Just to offer another option.  Though not as concise as _memo’s solution, but it does allow you to easily expand your options list just by adding additional values to the options key.

function UnitScan\_onAdvancedOptionClose() local options = { 'duration', 'stack' } for i=1, #options do local option = options[i] if not db[option] then db[option] = { minimum = {}, maximum = {} } end db[option].minimum = { enabled = ["min"..option].cbutton:GetChecked(), value = tonumber(["min"..option].ebox:GetText()) } db[option].maximum = { enable = ["max"..option].cbutton:GetChecked(), value = tonumber(["max"..option].ebox:GetText()) } end end

Best.

This code generate an error:

unexpected symbol near “[”

In correspondence of line 

enabled = [“min”…option].cbutton:GetChecked(),