kalekundert / byoc

MIT License
0 stars 0 forks source link

Set multiple parameters from a single value #45

Closed kalekundert closed 2 years ago

kalekundert commented 2 years ago

One thing that BYOC doesn't naturally handle well are config values that specify multiple parameters. For example:

class Time:
    hour = byoc.param()
    minute = byoc.param()
# config.toml
time = '12:30'

Here, we need to do some string parsing on the config value to separate the hour and the minute. The result of this parsing, though, needs to be saved to two different parameters. There are three ways to handle this currently:

Today I was thinking about a better way to handle this. My idea is to have cast functions that are shared between multiple parameters. Whenever the function is evaluated for one parameter, all of the others (if stale) are updated as well. Here's what it might look like:

# As a cast function:
class Time:
    hour = byoc.param(
            Key(DocoptConfig, '--time', cast=shared(parse_time, 0)),
    )
    minute = byoc.param(
            Key(DocoptConfig, '--time', cast=shared(parse_time, 1)),
    )

# As a getter:
class Time:
    hour = byoc.param(
            SharedKey(DocoptConfig, '--time', cast=parse_time, index=0),
    )
    minute = byoc.param(
            SharedKey(DocoptConfig, '--time', cast=parse_time, index=1),
    )

def parse_time(time_str):
    return time_str.split(':')

Some thoughts:

kalekundert commented 2 years ago

Recently I've been thinking that it was a mistake to cache bound getters, but this is a case where I need them to be cached (and the cache isn't working right). Maybe this is a good opportunity to change the way I cache bound getters: