Skip to content

Refactor SetConstant to use a lookup table#20

Open
RealRanger wants to merge 2 commits into
MadStudioRoblox:mainfrom
RealRanger:main
Open

Refactor SetConstant to use a lookup table#20
RealRanger wants to merge 2 commits into
MadStudioRoblox:mainfrom
RealRanger:main

Conversation

@RealRanger

Copy link
Copy Markdown

The current implementation of ProfileStore.SetConstant relies on a long if/else chain to assign values. While it works, this approach:

  • Is verbose and harder to maintain
  • Increases the risk of typos

Solution

Refactored ProfileStore.SetConstant to use a private lookup table (_constantSetters) scoped in ProfileStore.

  • Each constant name maps to a setter function that updates the corresponding constant.
  • The rest of the codebase still used the same global constants; no breaking changes.
  • New constants only require one new line in the lookup table.

Benefits

  • Cleaner, more maintainable code
  • Reduced risk of errors when expanding or changing the constants set

@Coffilhg Coffilhg left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. You might also make setters perfectly safe, e.g. ProfileStore.SetConstant("AUTO_SAVE_PERIOD") would reset the value to default, like you could make the setter callback be:

AUTO_SAVE_PERIOD = function(v)
  if type(v) ~= `number` then
    warn(`[{script.Name}]: SetConstant "AUTO_SAVE_PERIOD" ~> A number expected, got {type(v)}; Resetting to default value of 300`)
    AUTO_SAVE_PERIOD = 300
    return
  end
  AUTO_SAVE_PERIOD = v
end

@RealRanger

Copy link
Copy Markdown
Author

That makes sense. You might also make setters perfectly safe, e.g. ProfileStore.SetConstant("AUTO_SAVE_PERIOD") would reset the value to default, like you could make the setter callback be:

AUTO_SAVE_PERIOD = function(v)
  if type(v) ~= `number` then
    warn(`[{script.Name}]: SetConstant "AUTO_SAVE_PERIOD" ~> A number expected, got {type(v)}; Resetting to default value of 300`)
    AUTO_SAVE_PERIOD = 300
    return
  end
  AUTO_SAVE_PERIOD = v
end

Good idea; I’ve updated the setters to reflect this suggestion. Each one goes through a SafeSet utility, which enforces the type check and returns either the valid number or the default. That means even if someone bypasses SetConstant and calls a setter directly, it still goes through SafeSet and can’t corrupt the constant.

@RealRanger RealRanger requested a review from Coffilhg June 13, 2026 13:36

@Coffilhg Coffilhg left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! This is almost perfect now.
I'm surprised all of the settings are numbers. But for convenience of future changes we might make it more flexible. There's also a little thing we forgot about that errors if we input non-number value instead of setting the defaultValue at the start of the SetConstant method.

The changes would look something like:

-- a lot of original code

local function SafeSet(name, v)
    -- we could cache DEFAULTS[name] once (micro-optimization to reduce table accesses]
    local defaultValue = DEFAULTS[name]
    local defaultType = type(defaultValue)
    local inputType = type(v)
    
    if inputType ~= defaultType then
        warn(`[{script.Name}]: SetConstant {name} ~> A {defaultType} was expected, got {inputType}; Resetting to default value of {defaultValue}`)
        return defaultValue
    end
    return v
end

-- note: type() is limited to basic datatypes, if we want to support Roblox datatypes too, we could use typeof() instead of type() in SafeSet

-- a lot of original code

function ProfileStore.SetConstant(name, value)
    -- this one is not necessary, we have SafeSet to handle this
    -- if type(value) ~= "number" then
    --     error(`[{script.Name}]: Invalid value type`)
    -- end
    -- everything else unchanged
    local setter = ProfileStore._constantSetters[name]
    if setter then
        setter(value)
    else
        error(`[{script.Name}]: Invalid constant name was provided`)
    end
end

-- a lot of original code

lastly you could make the type ConstantName become the product of doing keyof of DEFAULTS, so this becomes very flexible - you only change DEFAULTS and it works.

Once you're done, you could commit to the V2 fork I made - https://github.com/Coffilhg/ProfileStoreV2

(Only if you want to)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants