Home of the Squeezebox™ & Transporter® network music players.
Results 1 to 7 of 7
  1. #1
    Senior Member
    Join Date
    May 2008
    Location
    Canada
    Posts
    5,055

    prefs for checkboxes (boolean)

    Hi - A question on YT plugin reminded me of an issue I had with preferences and I can't remember if that has already been discussed. To set defaults prefs, my plugins do a $prefs->init( { key1 = >value1, ke2 => value2 }); at startup.
    The problem is that when letting LMS handle preferences automatically, an unchecked box is stored in the .prefs file as "~" and at next plugin (LMS) startup, it is considered as non-set so if the default value is "1/on", then user choice is overwritten again and again.
    Do I miss something?
    LMS 7.7, 7.8 and 7.9 - 5xRadio, 3xBoom, 4xDuet, 1xTouch, 1 SB2. Sonos PLAY:3, PLAY:5, Marantz NR1603, JBL OnBeat, XBoxOne, XBMC, Foobar2000, ShairPortW, JRiver 21, 2xChromecast Audio, Chromecast v1 and v2, , Pi B3, B2, Pi B+, 2xPi A+, Odroid-C1, Odroid-C2, Cubie2, Yamaha WX-010, AppleTV 4, Airport Express, GGMM E5

  2. #2
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    20,314

    prefs for checkboxes (boolean)

    > The problem is that when letting LMS handle preferences automatically,
    > an unchecked box is stored in the .prefs file as "~" and at next plugin
    > (LMS) startup, it is considered as non-set so if the default value is
    > "1/on", then user choice is overwritten again and again.


    Haven't tested this right now, but that's indeed not what I'd expect to
    happen. IMHO "~" isn't "undefined", but "empty". I know that Perl
    sometimes is a bit vague on these. But the prefs init code should check
    undefined vs. defined only. I'd be surprised if with the gazillion of
    options we have in LMS this would not have cropped up before...

    Could it be a Perl version issue? Are you using a stock LMS package with
    the built-in binaries for YAML etc.?

    --

    Michael

  3. #3
    Senior Member
    Join Date
    May 2008
    Location
    Canada
    Posts
    5,055
    Quote Originally Posted by mherger View Post
    > The problem is that when letting LMS handle preferences automatically,
    > an unchecked box is stored in the .prefs file as "~" and at next plugin
    > (LMS) startup, it is considered as non-set so if the default value is
    > "1/on", then user choice is overwritten again and again.


    Haven't tested this right now, but that's indeed not what I'd expect to
    happen. IMHO "~" isn't "undefined", but "empty". I know that Perl
    sometimes is a bit vague on these. But the prefs init code should check
    undefined vs. defined only. I'd be surprised if with the gazillion of
    options we have in LMS this would not have cropped up before...

    Could it be a Perl version issue? Are you using a stock LMS package with
    the built-in binaries for YAML etc.?

    --

    Michael
    That was with my main LMS version:

    Logitech Media Server Version: 7.9.2 - 1564587295 @ Wed Jul 31 17:50:00 CEST 2019
    Hostname: multimedia
    Server IP Address: 192.168.2.144
    Server HTTP Port Number: 9000
    Operating system: Debian - EN - utf8
    Platform Architecture: armv7l-linux
    Perl Version: 5.24.1 - arm-linux-gnueabihf-thread-multi-64int
    Audio::Scan: 1.02
    IO::Socket::SSL: 2.044
    Database Version: DBD::SQLite 1.58 (sqlite 3.22.0)
    Total Players Recognized: 39

    I agree and this surprised me too, but I tried with a few of my plugins and look at the code of others and checked what is written in .prefs files
    I also found an old note I put for myself in one of my plugins where I decided to not set an init value to 1 for a checkbox prefs for this exact reason.
    The prefs code checks for "exist" or "defined" (in prefs/Base.pm)
    Code:
    if (!exists $class->{'prefs'}->{ $pref } || !defined $class->{'prefs'}->{ $pref }) {
    But I don't know yet how this hash is loaded from the .prefs file
    LMS 7.7, 7.8 and 7.9 - 5xRadio, 3xBoom, 4xDuet, 1xTouch, 1 SB2. Sonos PLAY:3, PLAY:5, Marantz NR1603, JBL OnBeat, XBoxOne, XBMC, Foobar2000, ShairPortW, JRiver 21, 2xChromecast Audio, Chromecast v1 and v2, , Pi B3, B2, Pi B+, 2xPi A+, Odroid-C1, Odroid-C2, Cubie2, Yamaha WX-010, AppleTV 4, Airport Express, GGMM E5

  4. #4
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    20,314

    prefs for checkboxes (boolean)

    First of all we seem to hardly use any checkboxes. And the ones I've
    found don't define a positive default value. Which probably tells us why
    there haven't been any complaints. Because the ~ indeed is a placeholder
    for the undefined value, not a defined but empty value
    (https://yaml.org/type/null.html).

    I guess a little patch is needed.

    --

    Michael

  5. #5
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    20,314
    Not sure about the patch any more: as we cannot know whether an empty value had been reset by a checkbox or something else, we can not rely on that value. This is really an issue only with values which a.) default to a non-empty value, and b.) use a checkbox as the UI element.

    I see two workarounds:

    • Don't use checkboxes, but other input methods. We often use a dropdown with the two choice descriptions as the labels.
    • Add a change handler which would override the undefined value with a defined, but falsy value:


    Code:
    	$prefs->setChange(sub {
    		my ($prefname, $value, $client) = @_;
    		if (!defined $value) {
    			$prefs->set($prefname, 0);
    		}
    	}, 'pref1', 'pref2', 'pref3', ...);
    As the init code only is being run during startup, this should be a safe method. Just make sure you really do check for undefined, or you might end up in an endless loop... you can add as many pref names to the setChange call as you need.
    Last edited by mherger; 2019-08-26 at 08:48.
    Michael

    http://www.herger.net/slim-plugins - Spotty, MusicArtistInfo

  6. #6
    Senior Member
    Join Date
    May 2010
    Location
    London, UK
    Posts
    390
    Quote Originally Posted by mherger View Post
    • Add a change handler which would override the undefined value with a defined, but falsy value:
    I think I ended up doing that, once. For what it's worth, here is a comment I wrote at some point:

    # Although logically 'undef' is equivalent to 0 in a boolean test, in SBS 7.8
    # the '$prefs->init' method considers 'undef' to be unitialized, so may give
    # unexpected behaviour.

    So perhaps there was a behaviour change in SBS 7.8, as I seem to have thought at the time.

  7. #7
    Senior Member
    Join Date
    May 2008
    Location
    Canada
    Posts
    5,055
    Quote Originally Posted by mherger View Post
    Not sure about the patch any more: as we cannot know whether an empty value had been reset by a checkbox or something else, we can not rely on that value. This is really an issue only with values which a.) default to a non-empty value, and b.) use a checkbox as the UI element.

    Code:
    	$prefs->setChange(sub {
    		my ($prefname, $value, $client) = @_;
    		if (!defined $value) {
    			$prefs->set($prefname, 0);
    		}
    	}, 'pref1', 'pref2', 'pref3', ...);
    As the init code only is being run during startup, this should be a safe method. Just make sure you really do check for undefined, or you might end up in an endless loop... you can add as many pref names to the setChange call as you need.
    I'll do that - Thank you as usual
    LMS 7.7, 7.8 and 7.9 - 5xRadio, 3xBoom, 4xDuet, 1xTouch, 1 SB2. Sonos PLAY:3, PLAY:5, Marantz NR1603, JBL OnBeat, XBoxOne, XBMC, Foobar2000, ShairPortW, JRiver 21, 2xChromecast Audio, Chromecast v1 and v2, , Pi B3, B2, Pi B+, 2xPi A+, Odroid-C1, Odroid-C2, Cubie2, Yamaha WX-010, AppleTV 4, Airport Express, GGMM E5

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •