-
Notifications
You must be signed in to change notification settings - Fork 222
Description
I just digged into the topic of how to use computed properties with Stencil because I had this issue in a project of mine.
This was already discussed here:
This bug report was closed because this feature was added:
- Dynamic member lookup
7247d0a
I was looking for something better compared to the workaround "don't use computed properties, always set regular properties instead". For example, if you want to pass a struct to Stencil like this and use the sum property:
struct Prices {
let prices: [Decimal]
var sum: Decimal {
prices.reduce(0, +)
}
}you could use something like this:
struct Prices {
let prices: [Decimal]
var sum: Decimal = 0
mutating func updateSum() {
self.sum = prices.reduce(0, +)
}
}I didn't like this solution too much, thus this bug report. The only clean alternative would be manually mapping the data types to Dictionary, which would mean a lot of manual busywork for complex types.
I tinkered with DynamicMemberLookup, you could add the sum property yourself, but then you loose the support for accessing other properties via the Mirror approach. One could copy the Mirror#getValue method from Stencil and use that as fallback, but looking at that method and the nil-handling I thought: no, better not.
I wondered:
Would it make sense to fall back to the Mirror-resolving if DynamicMemberLookup doesn't resolve a value? That way one could add code to add computed properties by manually resolving them.
So you could add something like this:
extension Prices: DynamicMemberLookup {
subscript(dynamicMember member: String) -> Any? {
if member == "sum" {
return self.sum
}
return nil
}
}and could still access the prices property without manually resolving it.
This currently is not possible, if it implements DynamicMemberLookup, it will not resolve via Mirror anymore:
Or maybe an extra protocol like DynamicMemberLookup that allows to add dynamic properties on top of the mirrored ones like that?