Closed samreid closed 5 years ago
The mutual exclusivity feature is catching occurrences in
where thumbNode
and thumbSize
are both being specified. It seems nice to be able to detect and prevent this kind of problem.
From slack:
Sam Reid [12:56 PM] I’m looking for library support for mutually exclusive options. Like if options.a was passed in, then options.b and options.c must not be passed in. And conversely, if options.b OR options.c was passed in, then options.a cannot be. Is there some lodash support for that? Or what is a good starting point?
Jonathan Olson [12:57 PM] I’m not aware of any. I think once for 3 options I ended up adding a count of providing options and asserting on that
Sam Reid [1:16 PM] Sounds good, thanks!
Sam Reid [2:02 PM] Is this too obtuse?
assert && assert(
Object.keys( _.pick( options, 'thumbNode' ) ).length *
Object.keys( _.pick( options, 'thumbSize', 'thumbFill', 'thumbFillHighlighted', 'thumbStroke', 'thumbLineWidth',
'thumbCenterLineStroke', 'thumbTouchAreaXDilation', 'thumbTouchAreaYDilation', 'thumbMouseAreaXDilation',
'thumbMouseAreaYDilation' ) ).length === 0,
'cannot provide both kinds of thumb options'
);
Michael Kauzmann [2:05 PM]
That looks pretty suave, what if it was hidden in a phetCore method like assertMutuallyExclusiveOptions( options, ...stringOrArrayOfString)
where each subsequent arg is an key or group of keys that are mutually exclusive with all other args.
Sam Reid [2:09 PM]
I literally have assert && assert( mutuallyExclusiveOptions(
in my local history. We are thinking along the same lines!
Michael Kauzmann [2:09 PM] nice!
Jonathan Olson [2:10 PM] That sounds nice to me
Sam Reid [2:11 PM] For this case, it will read like:
assert && assert( mutuallyExclusiveOptions( options, [ 'thumbNode' ], [
'thumbSize', 'thumbFill', 'thumbFillHighlighted', 'thumbStroke', 'thumbLineWidth', 'thumbCenterLineStroke',
'thumbTouchAreaXDilation', 'thumbTouchAreaYDilation', 'thumbMouseAreaXDilation', 'thumbMouseAreaYDilation'
] ), 'cannot provide both kinds of thumb options' );
Michael Kauzmann [2:12 PM] so fun!
I found I could get a better assert message if switching to assertMutuallyExclusiveOptions
, so I've moved in that direction.
I committed to master, this part is ready for review. Currently the only usage is in Slider.js which will be up for review soon as part of https://github.com/phetsims/scenery-phet/issues/498.
In https://github.com/phetsims/scenery-phet/issues/498#issuecomment-499654770, @pixelzoom said:
assertMutuallyExclusiveOptions looks generally useful, and appropriate to use here.
Anything else for this part? Do we need to survey other places to use this, or have a public service announcement about it?
Do we need to survey other places to use this, or have a public service announcement about it?
I'm guessing that cost to survey other places to use this outweighs benefits. So I don't think it's necessary.
A PSA for new features is always useful.
Feel free to close.
Marking for dev meeting public service announcement.
UPDATE: To clarify, we now have a utility that throws assertion errors when mutually exclusive options are provided. Please search for assertMutuallyExclusiveOptions(
for usage examples.
@ariel-phet requested to discuss this at another dev meeting when there are more developers.
Marking as high priority so this gets PSA'ed
8/8/19 dev meeting: @samreid will add doc for const assertMutuallyExclusiveOptions = function( options, ...sets )
, then close.
Documented as prescribed, closing.
From https://github.com/phetsims/scenery-phet/issues/498#issuecomment-498109080
A note about mutually exclusive options. Slider.js already has this code:
I don't see any logic about requiring these options to be mutually exclusive. Similar options will be added for track, and I created a library for asserting the options are mutually exclusive. In the case of the track, the usage is like so:
This works great for Slider. However, NumberControl supplies these default options whether or not
trackNode
orthumbNode
are passed in:My choices are to (a) forego checks for mutual exclusivity until further discussion or (b) to only have NumberControl override defaults if
thumbNode
ortrackNode
are not supplied. I'm inclined to go with (b), but this will probably require discussion.